1 use hal::{
2     adapter::MemoryProperties,
3     buffer,
4     device,
5     format,
6     image,
7     memory,
8     pass,
9     pool,
10     pso,
11     pso::VertexInputRate,
12     query,
13     queue::QueueFamilyId,
14     window,
15 };
16 
17 use winapi::{
18     shared::{
19         dxgi::{IDXGIFactory, IDXGISwapChain, DXGI_SWAP_CHAIN_DESC, DXGI_SWAP_EFFECT_DISCARD},
20         dxgiformat,
21         dxgitype,
22         minwindef::TRUE,
23         windef::HWND,
24         winerror,
25     },
26     um::{d3d11, d3d11sdklayers, d3dcommon},
27     Interface as _,
28 };
29 
30 use wio::com::ComPtr;
31 
32 use std::{borrow::Borrow, cell::RefCell, fmt, mem, ops::Range, ptr, sync::Arc};
33 
34 use parking_lot::{Condvar, Mutex};
35 
36 use crate::{
37     conv,
38     internal,
39     shader,
40     Backend,
41     Buffer,
42     BufferView,
43     CommandBuffer,
44     CommandPool,
45     ComputePipeline,
46     DescriptorContent,
47     DescriptorIndex,
48     DescriptorPool,
49     DescriptorSet,
50     DescriptorSetInfo,
51     DescriptorSetLayout,
52     Fence,
53     Framebuffer,
54     GraphicsPipeline,
55     Image,
56     ImageView,
57     InternalBuffer,
58     InternalImage,
59     Memory,
60     MultiStageData,
61     PipelineLayout,
62     QueryPool,
63     RawFence,
64     RegisterAccumulator,
65     RegisterData,
66     RenderPass,
67     ResourceIndex,
68     Sampler,
69     Semaphore,
70     ShaderModule,
71     SubpassDesc,
72     Surface,
73     Swapchain,
74     ViewInfo,
75 };
76 
77 //TODO: expose coherent type 0x2 when it's properly supported
78 const BUFFER_TYPE_MASK: u64 = 0x1 | 0x4;
79 
80 struct InputLayout {
81     raw: ComPtr<d3d11::ID3D11InputLayout>,
82     required_bindings: u32,
83     max_vertex_bindings: u32,
84     topology: d3d11::D3D11_PRIMITIVE_TOPOLOGY,
85     vertex_strides: Vec<u32>,
86 }
87 
88 pub struct Device {
89     raw: ComPtr<d3d11::ID3D11Device>,
90     pub(crate) context: ComPtr<d3d11::ID3D11DeviceContext>,
91     features: hal::Features,
92     memory_properties: MemoryProperties,
93     pub(crate) internal: internal::Internal,
94 }
95 
96 impl fmt::Debug for Device {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result97     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
98         fmt.write_str("Device")
99     }
100 }
101 
102 impl Drop for Device {
drop(&mut self)103     fn drop(&mut self) {
104         if let Ok(debug) = self.raw.cast::<d3d11sdklayers::ID3D11Debug>() {
105             unsafe {
106                 debug.ReportLiveDeviceObjects(d3d11sdklayers::D3D11_RLDO_DETAIL);
107             }
108         }
109     }
110 }
111 
112 unsafe impl Send for Device {}
113 unsafe impl Sync for Device {}
114 
115 impl Device {
new( device: ComPtr<d3d11::ID3D11Device>, context: ComPtr<d3d11::ID3D11DeviceContext>, features: hal::Features, memory_properties: MemoryProperties, ) -> Self116     pub fn new(
117         device: ComPtr<d3d11::ID3D11Device>,
118         context: ComPtr<d3d11::ID3D11DeviceContext>,
119         features: hal::Features,
120         memory_properties: MemoryProperties,
121     ) -> Self {
122         Device {
123             raw: device.clone(),
124             context,
125             features,
126             memory_properties,
127             internal: internal::Internal::new(&device),
128         }
129     }
130 
as_raw(&self) -> *mut d3d11::ID3D11Device131     pub fn as_raw(&self) -> *mut d3d11::ID3D11Device {
132         self.raw.as_raw()
133     }
134 
create_rasterizer_state( &self, rasterizer_desc: &pso::Rasterizer, ) -> Result<ComPtr<d3d11::ID3D11RasterizerState>, pso::CreationError>135     fn create_rasterizer_state(
136         &self,
137         rasterizer_desc: &pso::Rasterizer,
138     ) -> Result<ComPtr<d3d11::ID3D11RasterizerState>, pso::CreationError> {
139         let mut rasterizer = ptr::null_mut();
140         let desc = conv::map_rasterizer_desc(rasterizer_desc);
141 
142         let hr = unsafe {
143             self.raw
144                 .CreateRasterizerState(&desc, &mut rasterizer as *mut *mut _ as *mut *mut _)
145         };
146 
147         if winerror::SUCCEEDED(hr) {
148             Ok(unsafe { ComPtr::from_raw(rasterizer) })
149         } else {
150             Err(pso::CreationError::Other)
151         }
152     }
153 
create_blend_state( &self, blend_desc: &pso::BlendDesc, ) -> Result<ComPtr<d3d11::ID3D11BlendState>, pso::CreationError>154     fn create_blend_state(
155         &self,
156         blend_desc: &pso::BlendDesc,
157     ) -> Result<ComPtr<d3d11::ID3D11BlendState>, pso::CreationError> {
158         let mut blend = ptr::null_mut();
159         let desc = conv::map_blend_desc(blend_desc);
160 
161         let hr = unsafe {
162             self.raw
163                 .CreateBlendState(&desc, &mut blend as *mut *mut _ as *mut *mut _)
164         };
165 
166         if winerror::SUCCEEDED(hr) {
167             Ok(unsafe { ComPtr::from_raw(blend) })
168         } else {
169             Err(pso::CreationError::Other)
170         }
171     }
172 
create_depth_stencil_state( &self, depth_desc: &pso::DepthStencilDesc, ) -> Result< ( ComPtr<d3d11::ID3D11DepthStencilState>, pso::State<pso::StencilValue>, ), pso::CreationError, >173     fn create_depth_stencil_state(
174         &self,
175         depth_desc: &pso::DepthStencilDesc,
176     ) -> Result<
177         (
178             ComPtr<d3d11::ID3D11DepthStencilState>,
179             pso::State<pso::StencilValue>,
180         ),
181         pso::CreationError,
182     > {
183         let mut depth = ptr::null_mut();
184         let (desc, stencil_ref) = conv::map_depth_stencil_desc(depth_desc);
185 
186         let hr = unsafe {
187             self.raw
188                 .CreateDepthStencilState(&desc, &mut depth as *mut *mut _ as *mut *mut _)
189         };
190 
191         if winerror::SUCCEEDED(hr) {
192             Ok((unsafe { ComPtr::from_raw(depth) }, stencil_ref))
193         } else {
194             Err(pso::CreationError::Other)
195         }
196     }
197 
create_input_layout( &self, vs: ComPtr<d3dcommon::ID3DBlob>, vertex_buffers: &[pso::VertexBufferDesc], attributes: &[pso::AttributeDesc], input_assembler: &pso::InputAssemblerDesc, ) -> Result<InputLayout, pso::CreationError>198     fn create_input_layout(
199         &self,
200         vs: ComPtr<d3dcommon::ID3DBlob>,
201         vertex_buffers: &[pso::VertexBufferDesc],
202         attributes: &[pso::AttributeDesc],
203         input_assembler: &pso::InputAssemblerDesc,
204     ) -> Result<InputLayout, pso::CreationError> {
205         let mut layout = ptr::null_mut();
206 
207         let mut vertex_strides = Vec::new();
208         let mut required_bindings = 0u32;
209         let mut max_vertex_bindings = 0u32;
210         for buffer in vertex_buffers {
211             required_bindings |= 1 << buffer.binding as u32;
212             max_vertex_bindings = max_vertex_bindings.max(1u32 + buffer.binding as u32);
213 
214             while vertex_strides.len() <= buffer.binding as usize {
215                 vertex_strides.push(0);
216             }
217 
218             vertex_strides[buffer.binding as usize] = buffer.stride;
219         }
220 
221         let input_elements = attributes
222             .iter()
223             .filter_map(|attrib| {
224                 let buffer_desc = match vertex_buffers
225                     .iter()
226                     .find(|buffer_desc| buffer_desc.binding == attrib.binding)
227                 {
228                     Some(buffer_desc) => buffer_desc,
229                     None => {
230                         // TODO:
231                         // L
232                         // error!("Couldn't find associated vertex buffer description {:?}", attrib.binding);
233                         return Some(Err(pso::CreationError::Other));
234                     }
235                 };
236 
237                 let (slot_class, step_rate) = match buffer_desc.rate {
238                     VertexInputRate::Vertex => (d3d11::D3D11_INPUT_PER_VERTEX_DATA, 0),
239                     VertexInputRate::Instance(divisor) => {
240                         (d3d11::D3D11_INPUT_PER_INSTANCE_DATA, divisor)
241                     }
242                 };
243                 let format = attrib.element.format;
244 
245                 Some(Ok(d3d11::D3D11_INPUT_ELEMENT_DESC {
246                     SemanticName: "TEXCOORD\0".as_ptr() as *const _, // Semantic name used by SPIRV-Cross
247                     SemanticIndex: attrib.location,
248                     Format: match conv::map_format(format) {
249                         Some(fm) => fm,
250                         None => {
251                             // TODO:
252                             // error!("Unable to find DXGI format for {:?}", format);
253                             return Some(Err(pso::CreationError::Other));
254                         }
255                     },
256                     InputSlot: attrib.binding as _,
257                     AlignedByteOffset: attrib.element.offset,
258                     InputSlotClass: slot_class,
259                     InstanceDataStepRate: step_rate as _,
260                 }))
261             })
262             .collect::<Result<Vec<_>, _>>()?;
263 
264         let hr = unsafe {
265             self.raw.CreateInputLayout(
266                 input_elements.as_ptr(),
267                 input_elements.len() as _,
268                 vs.GetBufferPointer(),
269                 vs.GetBufferSize(),
270                 &mut layout as *mut *mut _ as *mut *mut _,
271             )
272         };
273 
274         if winerror::SUCCEEDED(hr) {
275             let topology = conv::map_topology(input_assembler);
276 
277             Ok(InputLayout {
278                 raw: unsafe { ComPtr::from_raw(layout) },
279                 required_bindings,
280                 max_vertex_bindings,
281                 topology,
282                 vertex_strides,
283             })
284         } else {
285             Err(pso::CreationError::Other)
286         }
287     }
288 
create_vertex_shader( &self, blob: ComPtr<d3dcommon::ID3DBlob>, ) -> Result<ComPtr<d3d11::ID3D11VertexShader>, pso::CreationError>289     fn create_vertex_shader(
290         &self,
291         blob: ComPtr<d3dcommon::ID3DBlob>,
292     ) -> Result<ComPtr<d3d11::ID3D11VertexShader>, pso::CreationError> {
293         let mut vs = ptr::null_mut();
294 
295         let hr = unsafe {
296             self.raw.CreateVertexShader(
297                 blob.GetBufferPointer(),
298                 blob.GetBufferSize(),
299                 ptr::null_mut(),
300                 &mut vs as *mut *mut _ as *mut *mut _,
301             )
302         };
303 
304         if winerror::SUCCEEDED(hr) {
305             Ok(unsafe { ComPtr::from_raw(vs) })
306         } else {
307             Err(pso::CreationError::Other)
308         }
309     }
310 
create_pixel_shader( &self, blob: ComPtr<d3dcommon::ID3DBlob>, ) -> Result<ComPtr<d3d11::ID3D11PixelShader>, pso::CreationError>311     fn create_pixel_shader(
312         &self,
313         blob: ComPtr<d3dcommon::ID3DBlob>,
314     ) -> Result<ComPtr<d3d11::ID3D11PixelShader>, pso::CreationError> {
315         let mut ps = ptr::null_mut();
316 
317         let hr = unsafe {
318             self.raw.CreatePixelShader(
319                 blob.GetBufferPointer(),
320                 blob.GetBufferSize(),
321                 ptr::null_mut(),
322                 &mut ps as *mut *mut _ as *mut *mut _,
323             )
324         };
325 
326         if winerror::SUCCEEDED(hr) {
327             Ok(unsafe { ComPtr::from_raw(ps) })
328         } else {
329             Err(pso::CreationError::Other)
330         }
331     }
332 
create_geometry_shader( &self, blob: ComPtr<d3dcommon::ID3DBlob>, ) -> Result<ComPtr<d3d11::ID3D11GeometryShader>, pso::CreationError>333     fn create_geometry_shader(
334         &self,
335         blob: ComPtr<d3dcommon::ID3DBlob>,
336     ) -> Result<ComPtr<d3d11::ID3D11GeometryShader>, pso::CreationError> {
337         let mut gs = ptr::null_mut();
338 
339         let hr = unsafe {
340             self.raw.CreateGeometryShader(
341                 blob.GetBufferPointer(),
342                 blob.GetBufferSize(),
343                 ptr::null_mut(),
344                 &mut gs as *mut *mut _ as *mut *mut _,
345             )
346         };
347 
348         if winerror::SUCCEEDED(hr) {
349             Ok(unsafe { ComPtr::from_raw(gs) })
350         } else {
351             Err(pso::CreationError::Other)
352         }
353     }
354 
create_hull_shader( &self, blob: ComPtr<d3dcommon::ID3DBlob>, ) -> Result<ComPtr<d3d11::ID3D11HullShader>, pso::CreationError>355     fn create_hull_shader(
356         &self,
357         blob: ComPtr<d3dcommon::ID3DBlob>,
358     ) -> Result<ComPtr<d3d11::ID3D11HullShader>, pso::CreationError> {
359         let mut hs = ptr::null_mut();
360 
361         let hr = unsafe {
362             self.raw.CreateHullShader(
363                 blob.GetBufferPointer(),
364                 blob.GetBufferSize(),
365                 ptr::null_mut(),
366                 &mut hs as *mut *mut _ as *mut *mut _,
367             )
368         };
369 
370         if winerror::SUCCEEDED(hr) {
371             Ok(unsafe { ComPtr::from_raw(hs) })
372         } else {
373             Err(pso::CreationError::Other)
374         }
375     }
376 
create_domain_shader( &self, blob: ComPtr<d3dcommon::ID3DBlob>, ) -> Result<ComPtr<d3d11::ID3D11DomainShader>, pso::CreationError>377     fn create_domain_shader(
378         &self,
379         blob: ComPtr<d3dcommon::ID3DBlob>,
380     ) -> Result<ComPtr<d3d11::ID3D11DomainShader>, pso::CreationError> {
381         let mut ds = ptr::null_mut();
382 
383         let hr = unsafe {
384             self.raw.CreateDomainShader(
385                 blob.GetBufferPointer(),
386                 blob.GetBufferSize(),
387                 ptr::null_mut(),
388                 &mut ds as *mut *mut _ as *mut *mut _,
389             )
390         };
391 
392         if winerror::SUCCEEDED(hr) {
393             Ok(unsafe { ComPtr::from_raw(ds) })
394         } else {
395             Err(pso::CreationError::Other)
396         }
397     }
398 
create_compute_shader( &self, blob: ComPtr<d3dcommon::ID3DBlob>, ) -> Result<ComPtr<d3d11::ID3D11ComputeShader>, pso::CreationError>399     fn create_compute_shader(
400         &self,
401         blob: ComPtr<d3dcommon::ID3DBlob>,
402     ) -> Result<ComPtr<d3d11::ID3D11ComputeShader>, pso::CreationError> {
403         let mut cs = ptr::null_mut();
404 
405         let hr = unsafe {
406             self.raw.CreateComputeShader(
407                 blob.GetBufferPointer(),
408                 blob.GetBufferSize(),
409                 ptr::null_mut(),
410                 &mut cs as *mut *mut _ as *mut *mut _,
411             )
412         };
413 
414         if winerror::SUCCEEDED(hr) {
415             Ok(unsafe { ComPtr::from_raw(cs) })
416         } else {
417             Err(pso::CreationError::Other)
418         }
419     }
420 
421     // TODO: fix return type..
extract_entry_point( stage: pso::Stage, source: &pso::EntryPoint<Backend>, layout: &PipelineLayout, features: &hal::Features, ) -> Result<Option<ComPtr<d3dcommon::ID3DBlob>>, device::ShaderError>422     fn extract_entry_point(
423         stage: pso::Stage,
424         source: &pso::EntryPoint<Backend>,
425         layout: &PipelineLayout,
426         features: &hal::Features,
427     ) -> Result<Option<ComPtr<d3dcommon::ID3DBlob>>, device::ShaderError> {
428         // TODO: entrypoint stuff
429         match *source.module {
430             ShaderModule::Dxbc(ref _shader) => {
431                 unimplemented!()
432 
433                 // Ok(Some(shader))
434             }
435             ShaderModule::Spirv(ref raw_data) => Ok(shader::compile_spirv_entrypoint(
436                 raw_data, stage, source, layout, features,
437             )?),
438         }
439     }
440 
view_image_as_shader_resource( &self, info: &ViewInfo, ) -> Result<ComPtr<d3d11::ID3D11ShaderResourceView>, image::ViewCreationError>441     fn view_image_as_shader_resource(
442         &self,
443         info: &ViewInfo,
444     ) -> Result<ComPtr<d3d11::ID3D11ShaderResourceView>, image::ViewCreationError> {
445         let mut desc: d3d11::D3D11_SHADER_RESOURCE_VIEW_DESC = unsafe { mem::zeroed() };
446         desc.Format = info.format;
447         if desc.Format == dxgiformat::DXGI_FORMAT_D32_FLOAT_S8X24_UINT {
448             desc.Format = dxgiformat::DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
449         }
450 
451         #[allow(non_snake_case)]
452         let MostDetailedMip = info.range.levels.start as _;
453         #[allow(non_snake_case)]
454         let MipLevels = (info.range.levels.end - info.range.levels.start) as _;
455         #[allow(non_snake_case)]
456         let FirstArraySlice = info.range.layers.start as _;
457         #[allow(non_snake_case)]
458         let ArraySize = (info.range.layers.end - info.range.layers.start) as _;
459 
460         match info.view_kind {
461             image::ViewKind::D1 => {
462                 desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_TEXTURE1D;
463                 *unsafe { desc.u.Texture1D_mut() } = d3d11::D3D11_TEX1D_SRV {
464                     MostDetailedMip,
465                     MipLevels,
466                 }
467             }
468             image::ViewKind::D1Array => {
469                 desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
470                 *unsafe { desc.u.Texture1DArray_mut() } = d3d11::D3D11_TEX1D_ARRAY_SRV {
471                     MostDetailedMip,
472                     MipLevels,
473                     FirstArraySlice,
474                     ArraySize,
475                 }
476             }
477             image::ViewKind::D2 => {
478                 desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_TEXTURE2D;
479                 *unsafe { desc.u.Texture2D_mut() } = d3d11::D3D11_TEX2D_SRV {
480                     MostDetailedMip,
481                     MipLevels,
482                 }
483             }
484             image::ViewKind::D2Array => {
485                 desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
486                 *unsafe { desc.u.Texture2DArray_mut() } = d3d11::D3D11_TEX2D_ARRAY_SRV {
487                     MostDetailedMip,
488                     MipLevels,
489                     FirstArraySlice,
490                     ArraySize,
491                 }
492             }
493             image::ViewKind::D3 => {
494                 desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_TEXTURE3D;
495                 *unsafe { desc.u.Texture3D_mut() } = d3d11::D3D11_TEX3D_SRV {
496                     MostDetailedMip,
497                     MipLevels,
498                 }
499             }
500             image::ViewKind::Cube => {
501                 desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_TEXTURECUBE;
502                 *unsafe { desc.u.TextureCube_mut() } = d3d11::D3D11_TEXCUBE_SRV {
503                     MostDetailedMip,
504                     MipLevels,
505                 }
506             }
507             image::ViewKind::CubeArray => {
508                 desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
509                 *unsafe { desc.u.TextureCubeArray_mut() } = d3d11::D3D11_TEXCUBE_ARRAY_SRV {
510                     MostDetailedMip,
511                     MipLevels,
512                     First2DArrayFace: FirstArraySlice,
513                     NumCubes: ArraySize / 6,
514                 }
515             }
516         }
517 
518         let mut srv = ptr::null_mut();
519         let hr = unsafe {
520             self.raw.CreateShaderResourceView(
521                 info.resource,
522                 &desc,
523                 &mut srv as *mut *mut _ as *mut *mut _,
524             )
525         };
526 
527         if winerror::SUCCEEDED(hr) {
528             Ok(unsafe { ComPtr::from_raw(srv) })
529         } else {
530             Err(image::ViewCreationError::Unsupported)
531         }
532     }
533 
view_image_as_unordered_access( &self, info: &ViewInfo, ) -> Result<ComPtr<d3d11::ID3D11UnorderedAccessView>, image::ViewCreationError>534     fn view_image_as_unordered_access(
535         &self,
536         info: &ViewInfo,
537     ) -> Result<ComPtr<d3d11::ID3D11UnorderedAccessView>, image::ViewCreationError> {
538         let mut desc: d3d11::D3D11_UNORDERED_ACCESS_VIEW_DESC = unsafe { mem::zeroed() };
539         desc.Format = info.format;
540 
541         #[allow(non_snake_case)]
542         let MipSlice = info.range.levels.start as _;
543         #[allow(non_snake_case)]
544         let FirstArraySlice = info.range.layers.start as _;
545         #[allow(non_snake_case)]
546         let ArraySize = (info.range.layers.end - info.range.layers.start) as _;
547 
548         match info.view_kind {
549             image::ViewKind::D1 => {
550                 desc.ViewDimension = d3d11::D3D11_UAV_DIMENSION_TEXTURE1D;
551                 *unsafe { desc.u.Texture1D_mut() } = d3d11::D3D11_TEX1D_UAV {
552                     MipSlice: info.range.levels.start as _,
553                 }
554             }
555             image::ViewKind::D1Array => {
556                 desc.ViewDimension = d3d11::D3D11_UAV_DIMENSION_TEXTURE1DARRAY;
557                 *unsafe { desc.u.Texture1DArray_mut() } = d3d11::D3D11_TEX1D_ARRAY_UAV {
558                     MipSlice,
559                     FirstArraySlice,
560                     ArraySize,
561                 }
562             }
563             image::ViewKind::D2 => {
564                 desc.ViewDimension = d3d11::D3D11_UAV_DIMENSION_TEXTURE2D;
565                 *unsafe { desc.u.Texture2D_mut() } = d3d11::D3D11_TEX2D_UAV {
566                     MipSlice: info.range.levels.start as _,
567                 }
568             }
569             image::ViewKind::D2Array => {
570                 desc.ViewDimension = d3d11::D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
571                 *unsafe { desc.u.Texture2DArray_mut() } = d3d11::D3D11_TEX2D_ARRAY_UAV {
572                     MipSlice,
573                     FirstArraySlice,
574                     ArraySize,
575                 }
576             }
577             image::ViewKind::D3 => {
578                 desc.ViewDimension = d3d11::D3D11_UAV_DIMENSION_TEXTURE3D;
579                 *unsafe { desc.u.Texture3D_mut() } = d3d11::D3D11_TEX3D_UAV {
580                     MipSlice,
581                     FirstWSlice: FirstArraySlice,
582                     WSize: ArraySize,
583                 }
584             }
585             _ => unimplemented!(),
586         }
587 
588         let mut uav = ptr::null_mut();
589         let hr = unsafe {
590             self.raw.CreateUnorderedAccessView(
591                 info.resource,
592                 &desc,
593                 &mut uav as *mut *mut _ as *mut *mut _,
594             )
595         };
596 
597         if winerror::SUCCEEDED(hr) {
598             Ok(unsafe { ComPtr::from_raw(uav) })
599         } else {
600             Err(image::ViewCreationError::Unsupported)
601         }
602     }
603 
view_image_as_render_target( &self, info: &ViewInfo, ) -> Result<ComPtr<d3d11::ID3D11RenderTargetView>, image::ViewCreationError>604     pub(crate) fn view_image_as_render_target(
605         &self,
606         info: &ViewInfo,
607     ) -> Result<ComPtr<d3d11::ID3D11RenderTargetView>, image::ViewCreationError> {
608         let mut desc: d3d11::D3D11_RENDER_TARGET_VIEW_DESC = unsafe { mem::zeroed() };
609         desc.Format = info.format;
610 
611         #[allow(non_snake_case)]
612         let MipSlice = info.range.levels.start as _;
613         #[allow(non_snake_case)]
614         let FirstArraySlice = info.range.layers.start as _;
615         #[allow(non_snake_case)]
616         let ArraySize = (info.range.layers.end - info.range.layers.start) as _;
617 
618         match info.view_kind {
619             image::ViewKind::D1 => {
620                 desc.ViewDimension = d3d11::D3D11_RTV_DIMENSION_TEXTURE1D;
621                 *unsafe { desc.u.Texture1D_mut() } = d3d11::D3D11_TEX1D_RTV { MipSlice }
622             }
623             image::ViewKind::D1Array => {
624                 desc.ViewDimension = d3d11::D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
625                 *unsafe { desc.u.Texture1DArray_mut() } = d3d11::D3D11_TEX1D_ARRAY_RTV {
626                     MipSlice,
627                     FirstArraySlice,
628                     ArraySize,
629                 }
630             }
631             image::ViewKind::D2 => {
632                 desc.ViewDimension = d3d11::D3D11_RTV_DIMENSION_TEXTURE2D;
633                 *unsafe { desc.u.Texture2D_mut() } = d3d11::D3D11_TEX2D_RTV { MipSlice }
634             }
635             image::ViewKind::D2Array => {
636                 desc.ViewDimension = d3d11::D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
637                 *unsafe { desc.u.Texture2DArray_mut() } = d3d11::D3D11_TEX2D_ARRAY_RTV {
638                     MipSlice,
639                     FirstArraySlice,
640                     ArraySize,
641                 }
642             }
643             image::ViewKind::D3 => {
644                 desc.ViewDimension = d3d11::D3D11_RTV_DIMENSION_TEXTURE3D;
645                 *unsafe { desc.u.Texture3D_mut() } = d3d11::D3D11_TEX3D_RTV {
646                     MipSlice,
647                     FirstWSlice: FirstArraySlice,
648                     WSize: ArraySize,
649                 }
650             }
651             _ => unimplemented!(),
652         }
653 
654         let mut rtv = ptr::null_mut();
655         let hr = unsafe {
656             self.raw.CreateRenderTargetView(
657                 info.resource,
658                 &desc,
659                 &mut rtv as *mut *mut _ as *mut *mut _,
660             )
661         };
662 
663         if winerror::SUCCEEDED(hr) {
664             Ok(unsafe { ComPtr::from_raw(rtv) })
665         } else {
666             Err(image::ViewCreationError::Unsupported)
667         }
668     }
669 
view_image_as_depth_stencil( &self, info: &ViewInfo, ) -> Result<ComPtr<d3d11::ID3D11DepthStencilView>, image::ViewCreationError>670     fn view_image_as_depth_stencil(
671         &self,
672         info: &ViewInfo,
673     ) -> Result<ComPtr<d3d11::ID3D11DepthStencilView>, image::ViewCreationError> {
674         #![allow(non_snake_case)]
675 
676         let MipSlice = info.range.levels.start as _;
677         let FirstArraySlice = info.range.layers.start as _;
678         let ArraySize = (info.range.layers.end - info.range.layers.start) as _;
679         assert_eq!(info.range.levels.start + 1, info.range.levels.end);
680         assert!(info.range.layers.end <= info.kind.num_layers());
681 
682         let mut desc: d3d11::D3D11_DEPTH_STENCIL_VIEW_DESC = unsafe { mem::zeroed() };
683         desc.Format = info.format;
684 
685         match info.view_kind {
686             image::ViewKind::D2 => {
687                 desc.ViewDimension = d3d11::D3D11_DSV_DIMENSION_TEXTURE2D;
688                 *unsafe { desc.u.Texture2D_mut() } = d3d11::D3D11_TEX2D_DSV { MipSlice }
689             }
690             image::ViewKind::D2Array => {
691                 desc.ViewDimension = d3d11::D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
692                 *unsafe { desc.u.Texture2DArray_mut() } = d3d11::D3D11_TEX2D_ARRAY_DSV {
693                     MipSlice,
694                     FirstArraySlice,
695                     ArraySize,
696                 }
697             }
698             _ => unimplemented!(),
699         }
700 
701         let mut dsv = ptr::null_mut();
702         let hr = unsafe {
703             self.raw.CreateDepthStencilView(
704                 info.resource,
705                 &desc,
706                 &mut dsv as *mut *mut _ as *mut *mut _,
707             )
708         };
709 
710         if winerror::SUCCEEDED(hr) {
711             Ok(unsafe { ComPtr::from_raw(dsv) })
712         } else {
713             Err(image::ViewCreationError::Unsupported)
714         }
715     }
716 
create_swapchain_impl( &self, config: &window::SwapchainConfig, window_handle: HWND, factory: ComPtr<IDXGIFactory>, ) -> Result<(ComPtr<IDXGISwapChain>, dxgiformat::DXGI_FORMAT), window::CreationError>717     pub(crate) fn create_swapchain_impl(
718         &self,
719         config: &window::SwapchainConfig,
720         window_handle: HWND,
721         factory: ComPtr<IDXGIFactory>,
722     ) -> Result<(ComPtr<IDXGISwapChain>, dxgiformat::DXGI_FORMAT), window::CreationError> {
723         // TODO: use IDXGIFactory2 for >=11.1
724         // TODO: this function should be able to fail (Result)?
725 
726         debug!("{:#?}", config);
727         let non_srgb_format = conv::map_format_nosrgb(config.format).unwrap();
728 
729         let mut desc = DXGI_SWAP_CHAIN_DESC {
730             BufferDesc: dxgitype::DXGI_MODE_DESC {
731                 Width: config.extent.width,
732                 Height: config.extent.height,
733                 // TODO: should this grab max value of all monitor hz? vsync
734                 //       will clamp to current monitor anyways?
735                 RefreshRate: dxgitype::DXGI_RATIONAL {
736                     Numerator: 1,
737                     Denominator: 60,
738                 },
739                 Format: non_srgb_format,
740                 ScanlineOrdering: dxgitype::DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
741                 Scaling: dxgitype::DXGI_MODE_SCALING_UNSPECIFIED,
742             },
743             // TODO: msaa on backbuffer?
744             SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
745                 Count: 1,
746                 Quality: 0,
747             },
748             BufferUsage: dxgitype::DXGI_USAGE_RENDER_TARGET_OUTPUT
749                 | dxgitype::DXGI_USAGE_SHADER_INPUT,
750             BufferCount: config.image_count,
751             OutputWindow: window_handle,
752             // TODO:
753             Windowed: TRUE,
754             // TODO:
755             SwapEffect: DXGI_SWAP_EFFECT_DISCARD,
756             Flags: 0,
757         };
758 
759         let dxgi_swapchain = {
760             let mut swapchain: *mut IDXGISwapChain = ptr::null_mut();
761             let hr = unsafe {
762                 factory.CreateSwapChain(
763                     self.raw.as_raw() as *mut _,
764                     &mut desc as *mut _,
765                     &mut swapchain as *mut *mut _ as *mut *mut _,
766                 )
767             };
768             assert_eq!(hr, winerror::S_OK);
769 
770             unsafe { ComPtr::from_raw(swapchain) }
771         };
772         Ok((dxgi_swapchain, non_srgb_format))
773     }
774 }
775 
776 impl device::Device<Backend> for Device {
allocate_memory( &self, mem_type: hal::MemoryTypeId, size: u64, ) -> Result<Memory, device::AllocationError>777     unsafe fn allocate_memory(
778         &self,
779         mem_type: hal::MemoryTypeId,
780         size: u64,
781     ) -> Result<Memory, device::AllocationError> {
782         let vec = Vec::with_capacity(size as usize);
783         Ok(Memory {
784             properties: self.memory_properties.memory_types[mem_type.0].properties,
785             size,
786             mapped_ptr: vec.as_ptr() as *mut _,
787             host_visible: Some(RefCell::new(vec)),
788             local_buffers: RefCell::new(Vec::new()),
789             _local_images: RefCell::new(Vec::new()),
790         })
791     }
792 
create_command_pool( &self, _family: QueueFamilyId, _create_flags: pool::CommandPoolCreateFlags, ) -> Result<CommandPool, device::OutOfMemory>793     unsafe fn create_command_pool(
794         &self,
795         _family: QueueFamilyId,
796         _create_flags: pool::CommandPoolCreateFlags,
797     ) -> Result<CommandPool, device::OutOfMemory> {
798         // TODO:
799         Ok(CommandPool {
800             device: self.raw.clone(),
801             internal: self.internal.clone(),
802         })
803     }
804 
destroy_command_pool(&self, _pool: CommandPool)805     unsafe fn destroy_command_pool(&self, _pool: CommandPool) {
806         // automatic
807     }
808 
create_render_pass<'a, IA, IS, ID>( &self, attachments: IA, subpasses: IS, _dependencies: ID, ) -> Result<RenderPass, device::OutOfMemory> where IA: IntoIterator, IA::Item: Borrow<pass::Attachment>, IS: IntoIterator, IS::Item: Borrow<pass::SubpassDesc<'a>>, ID: IntoIterator, ID::Item: Borrow<pass::SubpassDependency>,809     unsafe fn create_render_pass<'a, IA, IS, ID>(
810         &self,
811         attachments: IA,
812         subpasses: IS,
813         _dependencies: ID,
814     ) -> Result<RenderPass, device::OutOfMemory>
815     where
816         IA: IntoIterator,
817         IA::Item: Borrow<pass::Attachment>,
818         IS: IntoIterator,
819         IS::Item: Borrow<pass::SubpassDesc<'a>>,
820         ID: IntoIterator,
821         ID::Item: Borrow<pass::SubpassDependency>,
822     {
823         Ok(RenderPass {
824             attachments: attachments
825                 .into_iter()
826                 .map(|attachment| attachment.borrow().clone())
827                 .collect(),
828             subpasses: subpasses
829                 .into_iter()
830                 .map(|desc| {
831                     let desc = desc.borrow();
832                     SubpassDesc {
833                         color_attachments: desc
834                             .colors
835                             .iter()
836                             .map(|color| color.borrow().clone())
837                             .collect(),
838                         depth_stencil_attachment: desc.depth_stencil.map(|d| *d),
839                         input_attachments: desc
840                             .inputs
841                             .iter()
842                             .map(|input| input.borrow().clone())
843                             .collect(),
844                         resolve_attachments: desc
845                             .resolves
846                             .iter()
847                             .map(|resolve| resolve.borrow().clone())
848                             .collect(),
849                     }
850                 })
851                 .collect(),
852         })
853     }
854 
create_pipeline_layout<IS, IR>( &self, set_layouts: IS, _push_constant_ranges: IR, ) -> Result<PipelineLayout, device::OutOfMemory> where IS: IntoIterator, IS::Item: Borrow<DescriptorSetLayout>, IR: IntoIterator, IR::Item: Borrow<(pso::ShaderStageFlags, Range<u32>)>,855     unsafe fn create_pipeline_layout<IS, IR>(
856         &self,
857         set_layouts: IS,
858         _push_constant_ranges: IR,
859     ) -> Result<PipelineLayout, device::OutOfMemory>
860     where
861         IS: IntoIterator,
862         IS::Item: Borrow<DescriptorSetLayout>,
863         IR: IntoIterator,
864         IR::Item: Borrow<(pso::ShaderStageFlags, Range<u32>)>,
865     {
866         let mut res_offsets = MultiStageData::<RegisterData<RegisterAccumulator>>::default();
867         let mut sets = Vec::new();
868         for set_layout in set_layouts {
869             let layout = set_layout.borrow();
870             sets.push(DescriptorSetInfo {
871                 bindings: Arc::clone(&layout.bindings),
872                 registers: res_offsets.advance(&layout.pool_mapping),
873             });
874         }
875 
876         //TODO: assert that res_offsets are within supported range
877 
878         Ok(PipelineLayout { sets })
879     }
880 
create_pipeline_cache( &self, _data: Option<&[u8]>, ) -> Result<(), device::OutOfMemory>881     unsafe fn create_pipeline_cache(
882         &self,
883         _data: Option<&[u8]>,
884     ) -> Result<(), device::OutOfMemory> {
885         Ok(())
886     }
887 
get_pipeline_cache_data(&self, _cache: &()) -> Result<Vec<u8>, device::OutOfMemory>888     unsafe fn get_pipeline_cache_data(&self, _cache: &()) -> Result<Vec<u8>, device::OutOfMemory> {
889         //empty
890         Ok(Vec::new())
891     }
892 
destroy_pipeline_cache(&self, _: ())893     unsafe fn destroy_pipeline_cache(&self, _: ()) {
894         //empty
895     }
896 
merge_pipeline_caches<I>(&self, _: &(), _: I) -> Result<(), device::OutOfMemory> where I: IntoIterator, I::Item: Borrow<()>,897     unsafe fn merge_pipeline_caches<I>(&self, _: &(), _: I) -> Result<(), device::OutOfMemory>
898     where
899         I: IntoIterator,
900         I::Item: Borrow<()>,
901     {
902         //empty
903         Ok(())
904     }
905 
create_graphics_pipeline<'a>( &self, desc: &pso::GraphicsPipelineDesc<'a, Backend>, _cache: Option<&()>, ) -> Result<GraphicsPipeline, pso::CreationError>906     unsafe fn create_graphics_pipeline<'a>(
907         &self,
908         desc: &pso::GraphicsPipelineDesc<'a, Backend>,
909         _cache: Option<&()>,
910     ) -> Result<GraphicsPipeline, pso::CreationError> {
911         let features = &self.features;
912         let build_shader = |stage: pso::Stage, source: Option<&pso::EntryPoint<'a, Backend>>| {
913             let source = match source {
914                 Some(src) => src,
915                 None => return Ok(None),
916             };
917 
918             Self::extract_entry_point(stage, source, desc.layout, features)
919                 .map_err(|err| pso::CreationError::Shader(err))
920         };
921 
922         let vs = build_shader(pso::Stage::Vertex, Some(&desc.shaders.vertex))?.unwrap();
923         let ps = build_shader(pso::Stage::Fragment, desc.shaders.fragment.as_ref())?;
924         let gs = build_shader(pso::Stage::Geometry, desc.shaders.geometry.as_ref())?;
925         let ds = build_shader(pso::Stage::Domain, desc.shaders.domain.as_ref())?;
926         let hs = build_shader(pso::Stage::Hull, desc.shaders.hull.as_ref())?;
927 
928         let layout = self.create_input_layout(
929             vs.clone(),
930             &desc.vertex_buffers,
931             &desc.attributes,
932             &desc.input_assembler,
933         )?;
934         let rasterizer_state = self.create_rasterizer_state(&desc.rasterizer)?;
935         let blend_state = self.create_blend_state(&desc.blender)?;
936         let depth_stencil_state = Some(self.create_depth_stencil_state(&desc.depth_stencil)?);
937 
938         let vs = self.create_vertex_shader(vs)?;
939         let ps = if let Some(blob) = ps {
940             Some(self.create_pixel_shader(blob)?)
941         } else {
942             None
943         };
944         let gs = if let Some(blob) = gs {
945             Some(self.create_geometry_shader(blob)?)
946         } else {
947             None
948         };
949         let ds = if let Some(blob) = ds {
950             Some(self.create_domain_shader(blob)?)
951         } else {
952             None
953         };
954         let hs = if let Some(blob) = hs {
955             Some(self.create_hull_shader(blob)?)
956         } else {
957             None
958         };
959 
960         Ok(GraphicsPipeline {
961             vs,
962             gs,
963             ds,
964             hs,
965             ps,
966             topology: layout.topology,
967             input_layout: layout.raw,
968             rasterizer_state,
969             blend_state,
970             depth_stencil_state,
971             baked_states: desc.baked_states.clone(),
972             required_bindings: layout.required_bindings,
973             max_vertex_bindings: layout.max_vertex_bindings,
974             strides: layout.vertex_strides,
975         })
976     }
977 
create_compute_pipeline<'a>( &self, desc: &pso::ComputePipelineDesc<'a, Backend>, _cache: Option<&()>, ) -> Result<ComputePipeline, pso::CreationError>978     unsafe fn create_compute_pipeline<'a>(
979         &self,
980         desc: &pso::ComputePipelineDesc<'a, Backend>,
981         _cache: Option<&()>,
982     ) -> Result<ComputePipeline, pso::CreationError> {
983         let features = &self.features;
984         let build_shader = |stage: pso::Stage, source: Option<&pso::EntryPoint<'a, Backend>>| {
985             let source = match source {
986                 Some(src) => src,
987                 None => return Ok(None),
988             };
989 
990             Self::extract_entry_point(stage, source, desc.layout, features)
991                 .map_err(|err| pso::CreationError::Shader(err))
992         };
993 
994         let cs = build_shader(pso::Stage::Compute, Some(&desc.shader))?.unwrap();
995         let cs = self.create_compute_shader(cs)?;
996 
997         Ok(ComputePipeline { cs })
998     }
999 
create_framebuffer<I>( &self, _renderpass: &RenderPass, attachments: I, extent: image::Extent, ) -> Result<Framebuffer, device::OutOfMemory> where I: IntoIterator, I::Item: Borrow<ImageView>,1000     unsafe fn create_framebuffer<I>(
1001         &self,
1002         _renderpass: &RenderPass,
1003         attachments: I,
1004         extent: image::Extent,
1005     ) -> Result<Framebuffer, device::OutOfMemory>
1006     where
1007         I: IntoIterator,
1008         I::Item: Borrow<ImageView>,
1009     {
1010         Ok(Framebuffer {
1011             attachments: attachments
1012                 .into_iter()
1013                 .map(|att| att.borrow().clone())
1014                 .collect(),
1015             layers: extent.depth as _,
1016         })
1017     }
1018 
create_shader_module( &self, raw_data: &[u32], ) -> Result<ShaderModule, device::ShaderError>1019     unsafe fn create_shader_module(
1020         &self,
1021         raw_data: &[u32],
1022     ) -> Result<ShaderModule, device::ShaderError> {
1023         Ok(ShaderModule::Spirv(raw_data.into()))
1024     }
1025 
create_buffer( &self, size: u64, usage: buffer::Usage, ) -> Result<Buffer, buffer::CreationError>1026     unsafe fn create_buffer(
1027         &self,
1028         size: u64,
1029         usage: buffer::Usage,
1030     ) -> Result<Buffer, buffer::CreationError> {
1031         use buffer::Usage;
1032 
1033         let mut bind = 0;
1034 
1035         if usage.contains(Usage::UNIFORM) {
1036             bind |= d3d11::D3D11_BIND_CONSTANT_BUFFER;
1037         }
1038         if usage.contains(Usage::VERTEX) {
1039             bind |= d3d11::D3D11_BIND_VERTEX_BUFFER;
1040         }
1041         if usage.contains(Usage::INDEX) {
1042             bind |= d3d11::D3D11_BIND_INDEX_BUFFER;
1043         }
1044 
1045         // TODO: >=11.1
1046         if usage.intersects(Usage::UNIFORM_TEXEL | Usage::STORAGE_TEXEL | Usage::TRANSFER_SRC) {
1047             bind |= d3d11::D3D11_BIND_SHADER_RESOURCE;
1048         }
1049 
1050         if usage.intersects(Usage::TRANSFER_DST | Usage::STORAGE) {
1051             bind |= d3d11::D3D11_BIND_UNORDERED_ACCESS;
1052         }
1053 
1054         // if `D3D11_BIND_CONSTANT_BUFFER` intersects with any other bind flag, we need to handle
1055         // it by creating two buffers. one with `D3D11_BIND_CONSTANT_BUFFER` and one with the rest
1056         let needs_disjoint_cb = bind & d3d11::D3D11_BIND_CONSTANT_BUFFER != 0
1057             && bind != d3d11::D3D11_BIND_CONSTANT_BUFFER;
1058 
1059         if needs_disjoint_cb {
1060             bind ^= d3d11::D3D11_BIND_CONSTANT_BUFFER;
1061         }
1062 
1063         fn up_align(x: u64, alignment: u64) -> u64 {
1064             (x + alignment - 1) & !(alignment - 1)
1065         }
1066 
1067         // constant buffer size need to be divisible by 16
1068         let size = if usage.contains(Usage::UNIFORM) {
1069             up_align(size, 16)
1070         } else {
1071             up_align(size, 4)
1072         };
1073 
1074         Ok(Buffer {
1075             internal: InternalBuffer {
1076                 raw: ptr::null_mut(),
1077                 disjoint_cb: if needs_disjoint_cb {
1078                     Some(ptr::null_mut())
1079                 } else {
1080                     None
1081                 },
1082                 srv: None,
1083                 uav: None,
1084                 usage,
1085             },
1086             properties: memory::Properties::empty(),
1087             bound_range: 0 .. 0,
1088             host_ptr: ptr::null_mut(),
1089             bind,
1090             requirements: memory::Requirements {
1091                 size,
1092                 alignment: 1,
1093                 type_mask: BUFFER_TYPE_MASK,
1094             },
1095         })
1096     }
1097 
get_buffer_requirements(&self, buffer: &Buffer) -> memory::Requirements1098     unsafe fn get_buffer_requirements(&self, buffer: &Buffer) -> memory::Requirements {
1099         buffer.requirements
1100     }
1101 
bind_buffer_memory( &self, memory: &Memory, offset: u64, buffer: &mut Buffer, ) -> Result<(), device::BindError>1102     unsafe fn bind_buffer_memory(
1103         &self,
1104         memory: &Memory,
1105         offset: u64,
1106         buffer: &mut Buffer,
1107     ) -> Result<(), device::BindError> {
1108         debug!(
1109             "usage={:?}, props={:b}",
1110             buffer.internal.usage, memory.properties
1111         );
1112 
1113         #[allow(non_snake_case)]
1114         let MiscFlags = if buffer.bind
1115             & (d3d11::D3D11_BIND_SHADER_RESOURCE | d3d11::D3D11_BIND_UNORDERED_ACCESS)
1116             != 0
1117         {
1118             d3d11::D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS
1119         } else {
1120             0
1121         };
1122 
1123         let initial_data = memory
1124             .host_visible
1125             .as_ref()
1126             .map(|p| d3d11::D3D11_SUBRESOURCE_DATA {
1127                 pSysMem: p.borrow().as_ptr().offset(offset as isize) as _,
1128                 SysMemPitch: 0,
1129                 SysMemSlicePitch: 0,
1130             });
1131 
1132         let raw = if memory.properties.contains(memory::Properties::DEVICE_LOCAL) {
1133             // device local memory
1134             let desc = d3d11::D3D11_BUFFER_DESC {
1135                 ByteWidth: buffer.requirements.size as _,
1136                 Usage: d3d11::D3D11_USAGE_DEFAULT,
1137                 BindFlags: buffer.bind,
1138                 CPUAccessFlags: 0,
1139                 MiscFlags,
1140                 StructureByteStride: if buffer.internal.usage.contains(buffer::Usage::TRANSFER_SRC)
1141                 {
1142                     4
1143                 } else {
1144                     0
1145                 },
1146             };
1147 
1148             let mut buffer: *mut d3d11::ID3D11Buffer = ptr::null_mut();
1149             let hr = self.raw.CreateBuffer(
1150                 &desc,
1151                 if let Some(data) = initial_data {
1152                     &data
1153                 } else {
1154                     ptr::null_mut()
1155                 },
1156                 &mut buffer as *mut *mut _ as *mut *mut _,
1157             );
1158 
1159             if !winerror::SUCCEEDED(hr) {
1160                 return Err(device::BindError::WrongMemory);
1161             }
1162 
1163             ComPtr::from_raw(buffer)
1164         } else {
1165             let desc = d3d11::D3D11_BUFFER_DESC {
1166                 ByteWidth: buffer.requirements.size as _,
1167                 // TODO: dynamic?
1168                 Usage: d3d11::D3D11_USAGE_DEFAULT,
1169                 BindFlags: buffer.bind,
1170                 CPUAccessFlags: 0,
1171                 MiscFlags,
1172                 StructureByteStride: if buffer.internal.usage.contains(buffer::Usage::TRANSFER_SRC)
1173                 {
1174                     4
1175                 } else {
1176                     0
1177                 },
1178             };
1179 
1180             let mut buffer: *mut d3d11::ID3D11Buffer = ptr::null_mut();
1181             let hr = self.raw.CreateBuffer(
1182                 &desc,
1183                 if let Some(data) = initial_data {
1184                     &data
1185                 } else {
1186                     ptr::null_mut()
1187                 },
1188                 &mut buffer as *mut *mut _ as *mut *mut _,
1189             );
1190 
1191             if !winerror::SUCCEEDED(hr) {
1192                 return Err(device::BindError::WrongMemory);
1193             }
1194 
1195             ComPtr::from_raw(buffer)
1196         };
1197 
1198         let disjoint_cb = if buffer.internal.disjoint_cb.is_some() {
1199             let desc = d3d11::D3D11_BUFFER_DESC {
1200                 ByteWidth: buffer.requirements.size as _,
1201                 Usage: d3d11::D3D11_USAGE_DEFAULT,
1202                 BindFlags: d3d11::D3D11_BIND_CONSTANT_BUFFER,
1203                 CPUAccessFlags: 0,
1204                 MiscFlags: 0,
1205                 StructureByteStride: 0,
1206             };
1207 
1208             let mut buffer: *mut d3d11::ID3D11Buffer = ptr::null_mut();
1209             let hr = self.raw.CreateBuffer(
1210                 &desc,
1211                 if let Some(data) = initial_data {
1212                     &data
1213                 } else {
1214                     ptr::null_mut()
1215                 },
1216                 &mut buffer as *mut *mut _ as *mut *mut _,
1217             );
1218 
1219             if !winerror::SUCCEEDED(hr) {
1220                 return Err(device::BindError::WrongMemory);
1221             }
1222 
1223             Some(buffer)
1224         } else {
1225             None
1226         };
1227 
1228         let srv = if buffer.bind & d3d11::D3D11_BIND_SHADER_RESOURCE != 0 {
1229             let mut desc = mem::zeroed::<d3d11::D3D11_SHADER_RESOURCE_VIEW_DESC>();
1230             desc.Format = dxgiformat::DXGI_FORMAT_R32_TYPELESS;
1231             desc.ViewDimension = d3dcommon::D3D11_SRV_DIMENSION_BUFFEREX;
1232             *desc.u.BufferEx_mut() = d3d11::D3D11_BUFFEREX_SRV {
1233                 FirstElement: 0,
1234                 // TODO: enforce alignment through HAL limits
1235                 NumElements: buffer.requirements.size as u32 / 4,
1236                 Flags: d3d11::D3D11_BUFFEREX_SRV_FLAG_RAW,
1237             };
1238 
1239             let mut srv = ptr::null_mut();
1240             let hr = self.raw.CreateShaderResourceView(
1241                 raw.as_raw() as *mut _,
1242                 &desc,
1243                 &mut srv as *mut *mut _ as *mut *mut _,
1244             );
1245 
1246             if !winerror::SUCCEEDED(hr) {
1247                 error!("CreateShaderResourceView failed: 0x{:x}", hr);
1248 
1249                 return Err(device::BindError::WrongMemory);
1250             }
1251 
1252             Some(srv)
1253         } else {
1254             None
1255         };
1256 
1257         let uav = if buffer.bind & d3d11::D3D11_BIND_UNORDERED_ACCESS != 0 {
1258             let mut desc = mem::zeroed::<d3d11::D3D11_UNORDERED_ACCESS_VIEW_DESC>();
1259             desc.Format = dxgiformat::DXGI_FORMAT_R32_TYPELESS;
1260             desc.ViewDimension = d3d11::D3D11_UAV_DIMENSION_BUFFER;
1261             *desc.u.Buffer_mut() = d3d11::D3D11_BUFFER_UAV {
1262                 FirstElement: 0,
1263                 NumElements: buffer.requirements.size as u32 / 4,
1264                 Flags: d3d11::D3D11_BUFFER_UAV_FLAG_RAW,
1265             };
1266 
1267             let mut uav = ptr::null_mut();
1268             let hr = self.raw.CreateUnorderedAccessView(
1269                 raw.as_raw() as *mut _,
1270                 &desc,
1271                 &mut uav as *mut *mut _ as *mut *mut _,
1272             );
1273 
1274             if !winerror::SUCCEEDED(hr) {
1275                 error!("CreateUnorderedAccessView failed: 0x{:x}", hr);
1276 
1277                 return Err(device::BindError::WrongMemory);
1278             }
1279 
1280             Some(uav)
1281         } else {
1282             None
1283         };
1284 
1285         let internal = InternalBuffer {
1286             raw: raw.into_raw(),
1287             disjoint_cb,
1288             srv,
1289             uav,
1290             usage: buffer.internal.usage,
1291         };
1292         let range = offset .. offset + buffer.requirements.size;
1293 
1294         memory.bind_buffer(range.clone(), internal.clone());
1295 
1296         let host_ptr = if let Some(vec) = &memory.host_visible {
1297             vec.borrow().as_ptr() as *mut _
1298         } else {
1299             ptr::null_mut()
1300         };
1301 
1302         buffer.internal = internal;
1303         buffer.properties = memory.properties;
1304         buffer.host_ptr = host_ptr;
1305         buffer.bound_range = range;
1306 
1307         Ok(())
1308     }
1309 
create_buffer_view( &self, _buffer: &Buffer, _format: Option<format::Format>, _range: buffer::SubRange, ) -> Result<BufferView, buffer::ViewCreationError>1310     unsafe fn create_buffer_view(
1311         &self,
1312         _buffer: &Buffer,
1313         _format: Option<format::Format>,
1314         _range: buffer::SubRange,
1315     ) -> Result<BufferView, buffer::ViewCreationError> {
1316         unimplemented!()
1317     }
1318 
create_image( &self, kind: image::Kind, mip_levels: image::Level, format: format::Format, _tiling: image::Tiling, usage: image::Usage, view_caps: image::ViewCapabilities, ) -> Result<Image, image::CreationError>1319     unsafe fn create_image(
1320         &self,
1321         kind: image::Kind,
1322         mip_levels: image::Level,
1323         format: format::Format,
1324         _tiling: image::Tiling,
1325         usage: image::Usage,
1326         view_caps: image::ViewCapabilities,
1327     ) -> Result<Image, image::CreationError> {
1328         use image::Usage;
1329         //
1330         // TODO: create desc
1331 
1332         let surface_desc = format.base_format().0.desc();
1333         let bytes_per_texel = surface_desc.bits / 8;
1334         let ext = kind.extent();
1335         let size = (ext.width * ext.height * ext.depth) as u64 * bytes_per_texel as u64;
1336         let compressed = surface_desc.is_compressed();
1337         let depth = format.is_depth();
1338 
1339         let mut bind = 0;
1340 
1341         if usage.intersects(Usage::TRANSFER_SRC | Usage::SAMPLED | Usage::STORAGE) {
1342             bind |= d3d11::D3D11_BIND_SHADER_RESOURCE;
1343         }
1344 
1345         // we cant get RTVs or UAVs on compressed & depth formats
1346         if !compressed && !depth {
1347             if usage.intersects(Usage::COLOR_ATTACHMENT | Usage::TRANSFER_DST) {
1348                 bind |= d3d11::D3D11_BIND_RENDER_TARGET;
1349             }
1350 
1351             if usage.intersects(Usage::TRANSFER_DST | Usage::STORAGE) {
1352                 bind |= d3d11::D3D11_BIND_UNORDERED_ACCESS;
1353             }
1354         }
1355 
1356         if usage.contains(Usage::DEPTH_STENCIL_ATTACHMENT) {
1357             bind |= d3d11::D3D11_BIND_DEPTH_STENCIL;
1358         }
1359 
1360         debug!("{:b}", bind);
1361 
1362         Ok(Image {
1363             internal: InternalImage {
1364                 raw: ptr::null_mut(),
1365                 copy_srv: None,
1366                 srv: None,
1367                 unordered_access_views: Vec::new(),
1368                 depth_stencil_views: Vec::new(),
1369                 render_target_views: Vec::new(),
1370             },
1371             decomposed_format: conv::DecomposedDxgiFormat::UNKNOWN,
1372             kind,
1373             mip_levels,
1374             format,
1375             usage,
1376             view_caps,
1377             bind,
1378             requirements: memory::Requirements {
1379                 size: size,
1380                 alignment: 1,
1381                 type_mask: 0x1, // device-local only
1382             },
1383         })
1384     }
1385 
get_image_requirements(&self, image: &Image) -> memory::Requirements1386     unsafe fn get_image_requirements(&self, image: &Image) -> memory::Requirements {
1387         image.requirements
1388     }
1389 
get_image_subresource_footprint( &self, _image: &Image, _sub: image::Subresource, ) -> image::SubresourceFootprint1390     unsafe fn get_image_subresource_footprint(
1391         &self,
1392         _image: &Image,
1393         _sub: image::Subresource,
1394     ) -> image::SubresourceFootprint {
1395         unimplemented!()
1396     }
1397 
bind_image_memory( &self, memory: &Memory, offset: u64, image: &mut Image, ) -> Result<(), device::BindError>1398     unsafe fn bind_image_memory(
1399         &self,
1400         memory: &Memory,
1401         offset: u64,
1402         image: &mut Image,
1403     ) -> Result<(), device::BindError> {
1404         use image::Usage;
1405         use memory::Properties;
1406 
1407         let base_format = image.format.base_format();
1408         let format_desc = base_format.0.desc();
1409 
1410         let compressed = format_desc.is_compressed();
1411         let depth = image.format.is_depth();
1412         let stencil = image.format.is_stencil();
1413 
1414         let (bind, usage, cpu) = if memory.properties == Properties::DEVICE_LOCAL {
1415             (image.bind, d3d11::D3D11_USAGE_DEFAULT, 0)
1416         } else if memory.properties
1417             == (Properties::DEVICE_LOCAL | Properties::CPU_VISIBLE | Properties::CPU_CACHED)
1418         {
1419             (
1420                 image.bind,
1421                 d3d11::D3D11_USAGE_DYNAMIC,
1422                 d3d11::D3D11_CPU_ACCESS_WRITE,
1423             )
1424         } else if memory.properties == (Properties::CPU_VISIBLE | Properties::CPU_CACHED) {
1425             (
1426                 0,
1427                 d3d11::D3D11_USAGE_STAGING,
1428                 d3d11::D3D11_CPU_ACCESS_READ | d3d11::D3D11_CPU_ACCESS_WRITE,
1429             )
1430         } else {
1431             unimplemented!()
1432         };
1433 
1434         let dxgi_format = conv::map_format(image.format).unwrap();
1435         let decomposed = conv::DecomposedDxgiFormat::from_dxgi_format(dxgi_format);
1436         let bpp = format_desc.bits as u32 / 8;
1437 
1438         let (view_kind, resource) = match image.kind {
1439             image::Kind::D1(width, layers) => {
1440                 let initial_data =
1441                     memory
1442                         .host_visible
1443                         .as_ref()
1444                         .map(|_p| d3d11::D3D11_SUBRESOURCE_DATA {
1445                             pSysMem: memory.mapped_ptr.offset(offset as isize) as _,
1446                             SysMemPitch: 0,
1447                             SysMemSlicePitch: 0,
1448                         });
1449 
1450                 let desc = d3d11::D3D11_TEXTURE1D_DESC {
1451                     Width: width,
1452                     MipLevels: image.mip_levels as _,
1453                     ArraySize: layers as _,
1454                     Format: decomposed.typeless,
1455                     Usage: usage,
1456                     BindFlags: bind,
1457                     CPUAccessFlags: cpu,
1458                     MiscFlags: 0,
1459                 };
1460 
1461                 let mut resource = ptr::null_mut();
1462                 let hr = self.raw.CreateTexture1D(
1463                     &desc,
1464                     if let Some(data) = initial_data {
1465                         &data
1466                     } else {
1467                         ptr::null_mut()
1468                     },
1469                     &mut resource as *mut *mut _ as *mut *mut _,
1470                 );
1471 
1472                 if !winerror::SUCCEEDED(hr) {
1473                     error!("CreateTexture1D failed: 0x{:x}", hr);
1474 
1475                     return Err(device::BindError::WrongMemory);
1476                 }
1477 
1478                 (image::ViewKind::D1Array, resource)
1479             }
1480             image::Kind::D2(width, height, layers, _) => {
1481                 let mut initial_datas = Vec::new();
1482 
1483                 for _layer in 0 .. layers {
1484                     for level in 0 .. image.mip_levels {
1485                         let width = image.kind.extent().at_level(level).width;
1486 
1487                         // TODO: layer offset?
1488                         initial_datas.push(d3d11::D3D11_SUBRESOURCE_DATA {
1489                             pSysMem: memory.mapped_ptr.offset(offset as isize) as _,
1490                             SysMemPitch: width * bpp,
1491                             SysMemSlicePitch: 0,
1492                         });
1493                     }
1494                 }
1495 
1496                 let desc = d3d11::D3D11_TEXTURE2D_DESC {
1497                     Width: width,
1498                     Height: height,
1499                     MipLevels: image.mip_levels as _,
1500                     ArraySize: layers as _,
1501                     Format: decomposed.typeless,
1502                     SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
1503                         Count: 1,
1504                         Quality: 0,
1505                     },
1506                     Usage: usage,
1507                     BindFlags: bind,
1508                     CPUAccessFlags: cpu,
1509                     MiscFlags: if image.view_caps.contains(image::ViewCapabilities::KIND_CUBE) {
1510                         d3d11::D3D11_RESOURCE_MISC_TEXTURECUBE
1511                     } else {
1512                         0
1513                     },
1514                 };
1515 
1516                 let mut resource = ptr::null_mut();
1517                 let hr = self.raw.CreateTexture2D(
1518                     &desc,
1519                     if !depth {
1520                         initial_datas.as_ptr()
1521                     } else {
1522                         ptr::null_mut()
1523                     },
1524                     &mut resource as *mut *mut _ as *mut *mut _,
1525                 );
1526 
1527                 if !winerror::SUCCEEDED(hr) {
1528                     error!("CreateTexture2D failed: 0x{:x}", hr);
1529 
1530                     return Err(device::BindError::WrongMemory);
1531                 }
1532 
1533                 (image::ViewKind::D2Array, resource)
1534             }
1535             image::Kind::D3(width, height, depth) => {
1536                 let initial_data =
1537                     memory
1538                         .host_visible
1539                         .as_ref()
1540                         .map(|_p| d3d11::D3D11_SUBRESOURCE_DATA {
1541                             pSysMem: memory.mapped_ptr.offset(offset as isize) as _,
1542                             SysMemPitch: width * bpp,
1543                             SysMemSlicePitch: width * height * bpp,
1544                         });
1545 
1546                 let desc = d3d11::D3D11_TEXTURE3D_DESC {
1547                     Width: width,
1548                     Height: height,
1549                     Depth: depth,
1550                     MipLevels: image.mip_levels as _,
1551                     Format: decomposed.typeless,
1552                     Usage: usage,
1553                     BindFlags: bind,
1554                     CPUAccessFlags: cpu,
1555                     MiscFlags: 0,
1556                 };
1557 
1558                 let mut resource = ptr::null_mut();
1559                 let hr = self.raw.CreateTexture3D(
1560                     &desc,
1561                     if let Some(data) = initial_data {
1562                         &data
1563                     } else {
1564                         ptr::null_mut()
1565                     },
1566                     &mut resource as *mut *mut _ as *mut *mut _,
1567                 );
1568 
1569                 if !winerror::SUCCEEDED(hr) {
1570                     error!("CreateTexture3D failed: 0x{:x}", hr);
1571 
1572                     return Err(device::BindError::WrongMemory);
1573                 }
1574 
1575                 (image::ViewKind::D3, resource)
1576             }
1577         };
1578 
1579         let mut unordered_access_views = Vec::new();
1580 
1581         if image.usage.contains(Usage::TRANSFER_DST) && !compressed && !depth {
1582             for mip in 0 .. image.mip_levels {
1583                 let view = ViewInfo {
1584                     resource: resource,
1585                     kind: image.kind,
1586                     caps: image::ViewCapabilities::empty(),
1587                     view_kind,
1588                     // TODO: we should be using `uav_format` rather than `copy_uav_format`, and share
1589                     //       the UAVs when the formats are identical
1590                     format: decomposed.copy_uav.unwrap(),
1591                     range: image::SubresourceRange {
1592                         aspects: format::Aspects::COLOR,
1593                         levels: mip .. (mip + 1),
1594                         layers: 0 .. image.kind.num_layers(),
1595                     },
1596                 };
1597 
1598                 unordered_access_views.push(
1599                     self.view_image_as_unordered_access(&view)
1600                         .map_err(|_| device::BindError::WrongMemory)?,
1601                 );
1602             }
1603         }
1604 
1605         let (copy_srv, srv) = if image.usage.contains(image::Usage::TRANSFER_SRC) {
1606             let mut view = ViewInfo {
1607                 resource: resource,
1608                 kind: image.kind,
1609                 caps: image::ViewCapabilities::empty(),
1610                 view_kind,
1611                 format: decomposed.copy_srv.unwrap(),
1612                 range: image::SubresourceRange {
1613                     aspects: format::Aspects::COLOR,
1614                     levels: 0 .. image.mip_levels,
1615                     layers: 0 .. image.kind.num_layers(),
1616                 },
1617             };
1618 
1619             let copy_srv = if !compressed {
1620                 Some(
1621                     self.view_image_as_shader_resource(&view)
1622                         .map_err(|_| device::BindError::WrongMemory)?,
1623                 )
1624             } else {
1625                 None
1626             };
1627 
1628             view.format = decomposed.srv.unwrap();
1629 
1630             let srv = if !depth && !stencil {
1631                 Some(
1632                     self.view_image_as_shader_resource(&view)
1633                         .map_err(|_| device::BindError::WrongMemory)?,
1634                 )
1635             } else {
1636                 None
1637             };
1638 
1639             (copy_srv, srv)
1640         } else {
1641             (None, None)
1642         };
1643 
1644         let mut render_target_views = Vec::new();
1645 
1646         if (image.usage.contains(image::Usage::COLOR_ATTACHMENT)
1647             || image.usage.contains(image::Usage::TRANSFER_DST))
1648             && !compressed
1649             && !depth
1650         {
1651             for layer in 0 .. image.kind.num_layers() {
1652                 for mip in 0 .. image.mip_levels {
1653                     let view = ViewInfo {
1654                         resource: resource,
1655                         kind: image.kind,
1656                         caps: image::ViewCapabilities::empty(),
1657                         view_kind,
1658                         format: decomposed.rtv.unwrap(),
1659                         range: image::SubresourceRange {
1660                             aspects: format::Aspects::COLOR,
1661                             levels: mip .. (mip + 1),
1662                             layers: layer .. (layer + 1),
1663                         },
1664                     };
1665 
1666                     render_target_views.push(
1667                         self.view_image_as_render_target(&view)
1668                             .map_err(|_| device::BindError::WrongMemory)?,
1669                     );
1670                 }
1671             }
1672         };
1673 
1674         let mut depth_stencil_views = Vec::new();
1675 
1676         if depth {
1677             for layer in 0 .. image.kind.num_layers() {
1678                 for mip in 0 .. image.mip_levels {
1679                     let view = ViewInfo {
1680                         resource: resource,
1681                         kind: image.kind,
1682                         caps: image::ViewCapabilities::empty(),
1683                         view_kind,
1684                         format: decomposed.dsv.unwrap(),
1685                         range: image::SubresourceRange {
1686                             aspects: format::Aspects::COLOR,
1687                             levels: mip .. (mip + 1),
1688                             layers: layer .. (layer + 1),
1689                         },
1690                     };
1691 
1692                     depth_stencil_views.push(
1693                         self.view_image_as_depth_stencil(&view)
1694                             .map_err(|_| device::BindError::WrongMemory)?,
1695                     );
1696                 }
1697             }
1698         }
1699 
1700         let internal = InternalImage {
1701             raw: resource,
1702             copy_srv,
1703             srv,
1704             unordered_access_views,
1705             depth_stencil_views,
1706             render_target_views,
1707         };
1708 
1709         image.decomposed_format = decomposed;
1710         image.internal = internal;
1711 
1712         Ok(())
1713     }
1714 
create_image_view( &self, image: &Image, view_kind: image::ViewKind, format: format::Format, _swizzle: format::Swizzle, range: image::SubresourceRange, ) -> Result<ImageView, image::ViewCreationError>1715     unsafe fn create_image_view(
1716         &self,
1717         image: &Image,
1718         view_kind: image::ViewKind,
1719         format: format::Format,
1720         _swizzle: format::Swizzle,
1721         range: image::SubresourceRange,
1722     ) -> Result<ImageView, image::ViewCreationError> {
1723         let is_array = image.kind.num_layers() > 1;
1724 
1725         let info = ViewInfo {
1726             resource: image.internal.raw,
1727             kind: image.kind,
1728             caps: image.view_caps,
1729             // D3D11 doesn't allow looking at a single slice of an array as a non-array
1730             view_kind: if is_array && view_kind == image::ViewKind::D2 {
1731                 image::ViewKind::D2Array
1732             } else if is_array && view_kind == image::ViewKind::D1 {
1733                 image::ViewKind::D1Array
1734             } else {
1735                 view_kind
1736             },
1737             format: conv::map_format(format).ok_or(image::ViewCreationError::BadFormat(format))?,
1738             range,
1739         };
1740 
1741         let srv_info = ViewInfo {
1742             format: conv::viewable_format(info.format),
1743             ..info.clone()
1744         };
1745 
1746         Ok(ImageView {
1747             format,
1748             srv_handle: if image.usage.intersects(image::Usage::SAMPLED) {
1749                 Some(self.view_image_as_shader_resource(&srv_info)?)
1750             } else {
1751                 None
1752             },
1753             rtv_handle: if image.usage.contains(image::Usage::COLOR_ATTACHMENT) {
1754                 Some(self.view_image_as_render_target(&info)?)
1755             } else {
1756                 None
1757             },
1758             uav_handle: if image.usage.contains(image::Usage::STORAGE) {
1759                 Some(self.view_image_as_unordered_access(&info)?)
1760             } else {
1761                 None
1762             },
1763             dsv_handle: if image.usage.contains(image::Usage::DEPTH_STENCIL_ATTACHMENT) {
1764                 Some(self.view_image_as_depth_stencil(&info)?)
1765             } else {
1766                 None
1767             },
1768         })
1769     }
1770 
create_sampler( &self, info: &image::SamplerDesc, ) -> Result<Sampler, device::AllocationError>1771     unsafe fn create_sampler(
1772         &self,
1773         info: &image::SamplerDesc,
1774     ) -> Result<Sampler, device::AllocationError> {
1775         assert!(info.normalized);
1776 
1777         let op = match info.comparison {
1778             Some(_) => d3d11::D3D11_FILTER_REDUCTION_TYPE_COMPARISON,
1779             None => d3d11::D3D11_FILTER_REDUCTION_TYPE_STANDARD,
1780         };
1781 
1782         let desc = d3d11::D3D11_SAMPLER_DESC {
1783             Filter: conv::map_filter(
1784                 info.min_filter,
1785                 info.mag_filter,
1786                 info.mip_filter,
1787                 op,
1788                 info.anisotropy_clamp,
1789             ),
1790             AddressU: conv::map_wrapping(info.wrap_mode.0),
1791             AddressV: conv::map_wrapping(info.wrap_mode.1),
1792             AddressW: conv::map_wrapping(info.wrap_mode.2),
1793             MipLODBias: info.lod_bias.0,
1794             MaxAnisotropy: info.anisotropy_clamp.map_or(0, |aniso| aniso as u32),
1795             ComparisonFunc: info.comparison.map_or(0, |comp| conv::map_comparison(comp)),
1796             BorderColor: info.border.into(),
1797             MinLOD: info.lod_range.start.0,
1798             MaxLOD: info.lod_range.end.0,
1799         };
1800 
1801         let mut sampler = ptr::null_mut();
1802         let hr = self
1803             .raw
1804             .CreateSamplerState(&desc, &mut sampler as *mut *mut _ as *mut *mut _);
1805 
1806         assert_eq!(true, winerror::SUCCEEDED(hr));
1807 
1808         Ok(Sampler {
1809             sampler_handle: ComPtr::from_raw(sampler),
1810         })
1811     }
1812 
create_descriptor_pool<I>( &self, _max_sets: usize, ranges: I, _flags: pso::DescriptorPoolCreateFlags, ) -> Result<DescriptorPool, device::OutOfMemory> where I: IntoIterator, I::Item: Borrow<pso::DescriptorRangeDesc>,1813     unsafe fn create_descriptor_pool<I>(
1814         &self,
1815         _max_sets: usize,
1816         ranges: I,
1817         _flags: pso::DescriptorPoolCreateFlags,
1818     ) -> Result<DescriptorPool, device::OutOfMemory>
1819     where
1820         I: IntoIterator,
1821         I::Item: Borrow<pso::DescriptorRangeDesc>,
1822     {
1823         let mut total = RegisterData::default();
1824         for range in ranges {
1825             let r = range.borrow();
1826             let content = DescriptorContent::from(r.ty);
1827             total.add_content_many(content, r.count as DescriptorIndex);
1828         }
1829 
1830         let max_stages = 6;
1831         let count = total.sum() * max_stages;
1832         Ok(DescriptorPool::with_capacity(count))
1833     }
1834 
create_descriptor_set_layout<I, J>( &self, layout_bindings: I, _immutable_samplers: J, ) -> Result<DescriptorSetLayout, device::OutOfMemory> where I: IntoIterator, I::Item: Borrow<pso::DescriptorSetLayoutBinding>, J: IntoIterator, J::Item: Borrow<Sampler>,1835     unsafe fn create_descriptor_set_layout<I, J>(
1836         &self,
1837         layout_bindings: I,
1838         _immutable_samplers: J,
1839     ) -> Result<DescriptorSetLayout, device::OutOfMemory>
1840     where
1841         I: IntoIterator,
1842         I::Item: Borrow<pso::DescriptorSetLayoutBinding>,
1843         J: IntoIterator,
1844         J::Item: Borrow<Sampler>,
1845     {
1846         let mut total = MultiStageData::<RegisterData<_>>::default();
1847         let mut bindings = layout_bindings
1848             .into_iter()
1849             .map(|b| b.borrow().clone())
1850             .collect::<Vec<_>>();
1851 
1852         for binding in bindings.iter() {
1853             let content = DescriptorContent::from(binding.ty);
1854             total.add_content(content, binding.stage_flags);
1855         }
1856 
1857         bindings.sort_by_key(|a| a.binding);
1858 
1859         let accum = total.map_register(|count| RegisterAccumulator {
1860             res_index: *count as ResourceIndex,
1861         });
1862 
1863         Ok(DescriptorSetLayout {
1864             bindings: Arc::new(bindings),
1865             pool_mapping: accum.to_mapping(),
1866         })
1867     }
1868 
write_descriptor_sets<'a, I, J>(&self, write_iter: I) where I: IntoIterator<Item = pso::DescriptorSetWrite<'a, Backend, J>>, J: IntoIterator, J::Item: Borrow<pso::Descriptor<'a, Backend>>,1869     unsafe fn write_descriptor_sets<'a, I, J>(&self, write_iter: I)
1870     where
1871         I: IntoIterator<Item = pso::DescriptorSetWrite<'a, Backend, J>>,
1872         J: IntoIterator,
1873         J::Item: Borrow<pso::Descriptor<'a, Backend>>,
1874     {
1875         for write in write_iter {
1876             let mut mapping = write
1877                 .set
1878                 .layout
1879                 .pool_mapping
1880                 .map_register(|mapping| mapping.offset);
1881             let binding_start = write
1882                 .set
1883                 .layout
1884                 .bindings
1885                 .iter()
1886                 .position(|binding| binding.binding == write.binding)
1887                 .unwrap();
1888             for binding in &write.set.layout.bindings[.. binding_start] {
1889                 let content = DescriptorContent::from(binding.ty);
1890                 mapping.add_content(content, binding.stage_flags);
1891             }
1892 
1893             for (binding, descriptor) in write.set.layout.bindings[binding_start ..]
1894                 .iter()
1895                 .zip(write.descriptors)
1896             {
1897                 let handles = match *descriptor.borrow() {
1898                     pso::Descriptor::Buffer(buffer, ref _sub) => RegisterData {
1899                         c: match buffer.internal.disjoint_cb {
1900                             Some(dj_buf) => dj_buf as *mut _,
1901                             None => buffer.internal.raw as *mut _,
1902                         },
1903                         t: buffer.internal.srv.map_or(ptr::null_mut(), |p| p as *mut _),
1904                         u: buffer.internal.uav.map_or(ptr::null_mut(), |p| p as *mut _),
1905                         s: ptr::null_mut(),
1906                     },
1907                     pso::Descriptor::Image(image, _layout) => RegisterData {
1908                         c: ptr::null_mut(),
1909                         t: image
1910                             .srv_handle
1911                             .clone()
1912                             .map_or(ptr::null_mut(), |h| h.as_raw() as *mut _),
1913                         u: image
1914                             .uav_handle
1915                             .clone()
1916                             .map_or(ptr::null_mut(), |h| h.as_raw() as *mut _),
1917                         s: ptr::null_mut(),
1918                     },
1919                     pso::Descriptor::Sampler(sampler) => RegisterData {
1920                         c: ptr::null_mut(),
1921                         t: ptr::null_mut(),
1922                         u: ptr::null_mut(),
1923                         s: sampler.sampler_handle.as_raw() as *mut _,
1924                     },
1925                     pso::Descriptor::CombinedImageSampler(image, _layout, sampler) => {
1926                         RegisterData {
1927                             c: ptr::null_mut(),
1928                             t: image
1929                                 .srv_handle
1930                                 .clone()
1931                                 .map_or(ptr::null_mut(), |h| h.as_raw() as *mut _),
1932                             u: image
1933                                 .uav_handle
1934                                 .clone()
1935                                 .map_or(ptr::null_mut(), |h| h.as_raw() as *mut _),
1936                             s: sampler.sampler_handle.as_raw() as *mut _,
1937                         }
1938                     }
1939                     pso::Descriptor::TexelBuffer(_buffer_view) => unimplemented!(),
1940                 };
1941 
1942                 let content = DescriptorContent::from(binding.ty);
1943                 if content.contains(DescriptorContent::CBV) {
1944                     let offsets = mapping.map_other(|map| map.c);
1945                     write
1946                         .set
1947                         .assign_stages(&offsets, binding.stage_flags, handles.c);
1948                 };
1949                 if content.contains(DescriptorContent::SRV) {
1950                     let offsets = mapping.map_other(|map| map.t);
1951                     write
1952                         .set
1953                         .assign_stages(&offsets, binding.stage_flags, handles.t);
1954                 };
1955                 if content.contains(DescriptorContent::UAV) {
1956                     let offsets = mapping.map_other(|map| map.u);
1957                     write
1958                         .set
1959                         .assign_stages(&offsets, binding.stage_flags, handles.u);
1960                 };
1961                 if content.contains(DescriptorContent::SAMPLER) {
1962                     let offsets = mapping.map_other(|map| map.s);
1963                     write
1964                         .set
1965                         .assign_stages(&offsets, binding.stage_flags, handles.s);
1966                 };
1967 
1968                 mapping.add_content(content, binding.stage_flags);
1969             }
1970         }
1971     }
1972 
copy_descriptor_sets<'a, I>(&self, copy_iter: I) where I: IntoIterator, I::Item: Borrow<pso::DescriptorSetCopy<'a, Backend>>,1973     unsafe fn copy_descriptor_sets<'a, I>(&self, copy_iter: I)
1974     where
1975         I: IntoIterator,
1976         I::Item: Borrow<pso::DescriptorSetCopy<'a, Backend>>,
1977     {
1978         for copy in copy_iter {
1979             let _copy = copy.borrow();
1980             //TODO
1981             /*
1982             for offset in 0 .. copy.count {
1983                 let (dst_ty, dst_handle_offset, dst_second_handle_offset) = copy
1984                     .dst_set
1985                     .get_handle_offset(copy.dst_binding + offset as u32);
1986                 let (src_ty, src_handle_offset, src_second_handle_offset) = copy
1987                     .src_set
1988                     .get_handle_offset(copy.src_binding + offset as u32);
1989                 assert_eq!(dst_ty, src_ty);
1990 
1991                 let dst_handle = copy.dst_set.handles.offset(dst_handle_offset as isize);
1992                 let src_handle = copy.dst_set.handles.offset(src_handle_offset as isize);
1993 
1994                 match dst_ty {
1995                     pso::DescriptorType::Image {
1996                         ty: pso::ImageDescriptorType::Sampled { with_sampler: true }
1997                     } => {
1998                         let dst_second_handle = copy
1999                             .dst_set
2000                             .handles
2001                             .offset(dst_second_handle_offset as isize);
2002                         let src_second_handle = copy
2003                             .dst_set
2004                             .handles
2005                             .offset(src_second_handle_offset as isize);
2006 
2007                         *dst_handle = *src_handle;
2008                         *dst_second_handle = *src_second_handle;
2009                     }
2010                     _ => *dst_handle = *src_handle,
2011                 }
2012             }*/
2013         }
2014     }
2015 
map_memory( &self, memory: &Memory, segment: memory::Segment, ) -> Result<*mut u8, device::MapError>2016     unsafe fn map_memory(
2017         &self,
2018         memory: &Memory,
2019         segment: memory::Segment,
2020     ) -> Result<*mut u8, device::MapError> {
2021         assert_eq!(memory.host_visible.is_some(), true);
2022 
2023         Ok(memory.mapped_ptr.offset(segment.offset as isize))
2024     }
2025 
unmap_memory(&self, memory: &Memory)2026     unsafe fn unmap_memory(&self, memory: &Memory) {
2027         assert_eq!(memory.host_visible.is_some(), true);
2028     }
2029 
flush_mapped_memory_ranges<'a, I>(&self, ranges: I) -> Result<(), device::OutOfMemory> where I: IntoIterator, I::Item: Borrow<(&'a Memory, memory::Segment)>,2030     unsafe fn flush_mapped_memory_ranges<'a, I>(&self, ranges: I) -> Result<(), device::OutOfMemory>
2031     where
2032         I: IntoIterator,
2033         I::Item: Borrow<(&'a Memory, memory::Segment)>,
2034     {
2035         let _scope = debug_scope!(&self.context, "FlushMappedRanges");
2036 
2037         // go through every range we wrote to
2038         for range in ranges.into_iter() {
2039             let &(memory, ref segment) = range.borrow();
2040             let range = memory.resolve(segment);
2041 
2042             let _scope = debug_scope!(&self.context, "Range({:?})", range);
2043             memory.flush(&self.context, range);
2044         }
2045 
2046         Ok(())
2047     }
2048 
invalidate_mapped_memory_ranges<'a, I>( &self, ranges: I, ) -> Result<(), device::OutOfMemory> where I: IntoIterator, I::Item: Borrow<(&'a Memory, memory::Segment)>,2049     unsafe fn invalidate_mapped_memory_ranges<'a, I>(
2050         &self,
2051         ranges: I,
2052     ) -> Result<(), device::OutOfMemory>
2053     where
2054         I: IntoIterator,
2055         I::Item: Borrow<(&'a Memory, memory::Segment)>,
2056     {
2057         let _scope = debug_scope!(&self.context, "InvalidateMappedRanges");
2058 
2059         // go through every range we want to read from
2060         for range in ranges.into_iter() {
2061             let &(memory, ref segment) = range.borrow();
2062             let range = memory.resolve(segment);
2063 
2064             let _scope = debug_scope!(&self.context, "Range({:?})", range);
2065             memory.invalidate(
2066                 &self.context,
2067                 range,
2068                 self.internal.working_buffer.clone(),
2069                 self.internal.working_buffer_size,
2070             );
2071         }
2072 
2073         Ok(())
2074     }
2075 
create_semaphore(&self) -> Result<Semaphore, device::OutOfMemory>2076     fn create_semaphore(&self) -> Result<Semaphore, device::OutOfMemory> {
2077         // TODO:
2078         Ok(Semaphore)
2079     }
2080 
create_fence(&self, signalled: bool) -> Result<Fence, device::OutOfMemory>2081     fn create_fence(&self, signalled: bool) -> Result<Fence, device::OutOfMemory> {
2082         Ok(Arc::new(RawFence {
2083             mutex: Mutex::new(signalled),
2084             condvar: Condvar::new(),
2085         }))
2086     }
2087 
reset_fence(&self, fence: &Fence) -> Result<(), device::OutOfMemory>2088     unsafe fn reset_fence(&self, fence: &Fence) -> Result<(), device::OutOfMemory> {
2089         *fence.mutex.lock() = false;
2090         Ok(())
2091     }
2092 
wait_for_fence( &self, fence: &Fence, timeout_ns: u64, ) -> Result<bool, device::OomOrDeviceLost>2093     unsafe fn wait_for_fence(
2094         &self,
2095         fence: &Fence,
2096         timeout_ns: u64,
2097     ) -> Result<bool, device::OomOrDeviceLost> {
2098         use std::time::{Duration, Instant};
2099 
2100         debug!("wait_for_fence {:?} for {} ns", fence, timeout_ns);
2101         let mut guard = fence.mutex.lock();
2102         match timeout_ns {
2103             0 => Ok(*guard),
2104             0xFFFFFFFFFFFFFFFF => {
2105                 while !*guard {
2106                     fence.condvar.wait(&mut guard);
2107                 }
2108                 Ok(true)
2109             }
2110             _ => {
2111                 let total = Duration::from_nanos(timeout_ns as u64);
2112                 let now = Instant::now();
2113                 while !*guard {
2114                     let duration = match total.checked_sub(now.elapsed()) {
2115                         Some(dur) => dur,
2116                         None => return Ok(false),
2117                     };
2118                     let result = fence.condvar.wait_for(&mut guard, duration);
2119                     if result.timed_out() {
2120                         return Ok(false);
2121                     }
2122                 }
2123                 Ok(true)
2124             }
2125         }
2126     }
2127 
get_fence_status(&self, fence: &Fence) -> Result<bool, device::DeviceLost>2128     unsafe fn get_fence_status(&self, fence: &Fence) -> Result<bool, device::DeviceLost> {
2129         Ok(*fence.mutex.lock())
2130     }
2131 
create_event(&self) -> Result<(), device::OutOfMemory>2132     fn create_event(&self) -> Result<(), device::OutOfMemory> {
2133         unimplemented!()
2134     }
2135 
get_event_status(&self, _event: &()) -> Result<bool, device::OomOrDeviceLost>2136     unsafe fn get_event_status(&self, _event: &()) -> Result<bool, device::OomOrDeviceLost> {
2137         unimplemented!()
2138     }
2139 
set_event(&self, _event: &()) -> Result<(), device::OutOfMemory>2140     unsafe fn set_event(&self, _event: &()) -> Result<(), device::OutOfMemory> {
2141         unimplemented!()
2142     }
2143 
reset_event(&self, _event: &()) -> Result<(), device::OutOfMemory>2144     unsafe fn reset_event(&self, _event: &()) -> Result<(), device::OutOfMemory> {
2145         unimplemented!()
2146     }
2147 
free_memory(&self, memory: Memory)2148     unsafe fn free_memory(&self, memory: Memory) {
2149         for (_range, internal) in memory.local_buffers.borrow_mut().iter() {
2150             (*internal.raw).Release();
2151             if let Some(srv) = internal.srv {
2152                 (*srv).Release();
2153             }
2154         }
2155     }
2156 
create_query_pool( &self, _query_ty: query::Type, _count: query::Id, ) -> Result<QueryPool, query::CreationError>2157     unsafe fn create_query_pool(
2158         &self,
2159         _query_ty: query::Type,
2160         _count: query::Id,
2161     ) -> Result<QueryPool, query::CreationError> {
2162         unimplemented!()
2163     }
2164 
destroy_query_pool(&self, _pool: QueryPool)2165     unsafe fn destroy_query_pool(&self, _pool: QueryPool) {
2166         unimplemented!()
2167     }
2168 
get_query_pool_results( &self, _pool: &QueryPool, _queries: Range<query::Id>, _data: &mut [u8], _stride: buffer::Offset, _flags: query::ResultFlags, ) -> Result<bool, device::OomOrDeviceLost>2169     unsafe fn get_query_pool_results(
2170         &self,
2171         _pool: &QueryPool,
2172         _queries: Range<query::Id>,
2173         _data: &mut [u8],
2174         _stride: buffer::Offset,
2175         _flags: query::ResultFlags,
2176     ) -> Result<bool, device::OomOrDeviceLost> {
2177         unimplemented!()
2178     }
2179 
destroy_shader_module(&self, _shader_lib: ShaderModule)2180     unsafe fn destroy_shader_module(&self, _shader_lib: ShaderModule) {}
2181 
destroy_render_pass(&self, _rp: RenderPass)2182     unsafe fn destroy_render_pass(&self, _rp: RenderPass) {
2183         //unimplemented!()
2184     }
2185 
destroy_pipeline_layout(&self, _layout: PipelineLayout)2186     unsafe fn destroy_pipeline_layout(&self, _layout: PipelineLayout) {
2187         //unimplemented!()
2188     }
2189 
destroy_graphics_pipeline(&self, _pipeline: GraphicsPipeline)2190     unsafe fn destroy_graphics_pipeline(&self, _pipeline: GraphicsPipeline) {}
2191 
destroy_compute_pipeline(&self, _pipeline: ComputePipeline)2192     unsafe fn destroy_compute_pipeline(&self, _pipeline: ComputePipeline) {}
2193 
destroy_framebuffer(&self, _fb: Framebuffer)2194     unsafe fn destroy_framebuffer(&self, _fb: Framebuffer) {}
2195 
destroy_buffer(&self, _buffer: Buffer)2196     unsafe fn destroy_buffer(&self, _buffer: Buffer) {}
2197 
destroy_buffer_view(&self, _view: BufferView)2198     unsafe fn destroy_buffer_view(&self, _view: BufferView) {
2199         unimplemented!()
2200     }
2201 
destroy_image(&self, _image: Image)2202     unsafe fn destroy_image(&self, _image: Image) {
2203         // TODO:
2204         // unimplemented!()
2205     }
2206 
destroy_image_view(&self, _view: ImageView)2207     unsafe fn destroy_image_view(&self, _view: ImageView) {
2208         //unimplemented!()
2209     }
2210 
destroy_sampler(&self, _sampler: Sampler)2211     unsafe fn destroy_sampler(&self, _sampler: Sampler) {}
2212 
destroy_descriptor_pool(&self, _pool: DescriptorPool)2213     unsafe fn destroy_descriptor_pool(&self, _pool: DescriptorPool) {
2214         //unimplemented!()
2215     }
2216 
destroy_descriptor_set_layout(&self, _layout: DescriptorSetLayout)2217     unsafe fn destroy_descriptor_set_layout(&self, _layout: DescriptorSetLayout) {
2218         //unimplemented!()
2219     }
2220 
destroy_fence(&self, _fence: Fence)2221     unsafe fn destroy_fence(&self, _fence: Fence) {
2222         // unimplemented!()
2223     }
2224 
destroy_semaphore(&self, _semaphore: Semaphore)2225     unsafe fn destroy_semaphore(&self, _semaphore: Semaphore) {
2226         //unimplemented!()
2227     }
2228 
destroy_event(&self, _event: ())2229     unsafe fn destroy_event(&self, _event: ()) {
2230         //unimplemented!()
2231     }
2232 
create_swapchain( &self, surface: &mut Surface, config: window::SwapchainConfig, _old_swapchain: Option<Swapchain>, ) -> Result<(Swapchain, Vec<Image>), window::CreationError>2233     unsafe fn create_swapchain(
2234         &self,
2235         surface: &mut Surface,
2236         config: window::SwapchainConfig,
2237         _old_swapchain: Option<Swapchain>,
2238     ) -> Result<(Swapchain, Vec<Image>), window::CreationError> {
2239         let (dxgi_swapchain, non_srgb_format) =
2240             self.create_swapchain_impl(&config, surface.wnd_handle, surface.factory.clone())?;
2241 
2242         let resource = {
2243             let mut resource: *mut d3d11::ID3D11Resource = ptr::null_mut();
2244             assert_eq!(
2245                 winerror::S_OK,
2246                 dxgi_swapchain.GetBuffer(
2247                     0 as _,
2248                     &d3d11::ID3D11Resource::uuidof(),
2249                     &mut resource as *mut *mut _ as *mut *mut _,
2250                 )
2251             );
2252             resource
2253         };
2254 
2255         let kind = image::Kind::D2(config.extent.width, config.extent.height, 1, 1);
2256         let decomposed =
2257             conv::DecomposedDxgiFormat::from_dxgi_format(conv::map_format(config.format).unwrap());
2258 
2259         let mut view_info = ViewInfo {
2260             resource,
2261             kind,
2262             caps: image::ViewCapabilities::empty(),
2263             view_kind: image::ViewKind::D2,
2264             format: decomposed.rtv.unwrap(),
2265             // TODO: can these ever differ for backbuffer?
2266             range: image::SubresourceRange {
2267                 aspects: format::Aspects::COLOR,
2268                 levels: 0 .. 1,
2269                 layers: 0 .. 1,
2270             },
2271         };
2272         let rtv = self.view_image_as_render_target(&view_info).unwrap();
2273 
2274         view_info.format = non_srgb_format;
2275         view_info.view_kind = image::ViewKind::D2Array;
2276         let copy_srv = self.view_image_as_shader_resource(&view_info).unwrap();
2277 
2278         let images = (0 .. config.image_count)
2279             .map(|_i| {
2280                 // returning the 0th buffer for all images seems like the right thing to do. we can
2281                 // only get write access to the first buffer in the case of `_SEQUENTIAL` flip model,
2282                 // and read access to the rest
2283                 let internal = InternalImage {
2284                     raw: resource,
2285                     copy_srv: Some(copy_srv.clone()),
2286                     srv: None,
2287                     unordered_access_views: Vec::new(),
2288                     depth_stencil_views: Vec::new(),
2289                     render_target_views: vec![rtv.clone()],
2290                 };
2291 
2292                 Image {
2293                     kind,
2294                     usage: config.image_usage,
2295                     format: config.format,
2296                     view_caps: image::ViewCapabilities::empty(),
2297                     // NOTE: not the actual format of the backbuffer(s)
2298                     decomposed_format: decomposed.clone(),
2299                     mip_levels: 1,
2300                     internal,
2301                     bind: 0, // TODO: ?
2302                     requirements: memory::Requirements {
2303                         // values don't really matter
2304                         size: 0,
2305                         alignment: 0,
2306                         type_mask: 0,
2307                     },
2308                 }
2309             })
2310             .collect();
2311 
2312         Ok((Swapchain { dxgi_swapchain }, images))
2313     }
2314 
destroy_swapchain(&self, _swapchain: Swapchain)2315     unsafe fn destroy_swapchain(&self, _swapchain: Swapchain) {
2316         // automatic
2317     }
2318 
wait_idle(&self) -> Result<(), device::OutOfMemory>2319     fn wait_idle(&self) -> Result<(), device::OutOfMemory> {
2320         Ok(())
2321         // unimplemented!()
2322     }
2323 
set_image_name(&self, _image: &mut Image, _name: &str)2324     unsafe fn set_image_name(&self, _image: &mut Image, _name: &str) {
2325         // TODO
2326     }
2327 
set_buffer_name(&self, _buffer: &mut Buffer, _name: &str)2328     unsafe fn set_buffer_name(&self, _buffer: &mut Buffer, _name: &str) {
2329         // TODO
2330     }
2331 
set_command_buffer_name(&self, _command_buffer: &mut CommandBuffer, _name: &str)2332     unsafe fn set_command_buffer_name(&self, _command_buffer: &mut CommandBuffer, _name: &str) {
2333         // TODO
2334     }
2335 
set_semaphore_name(&self, _semaphore: &mut Semaphore, _name: &str)2336     unsafe fn set_semaphore_name(&self, _semaphore: &mut Semaphore, _name: &str) {
2337         // TODO
2338     }
2339 
set_fence_name(&self, _fence: &mut Fence, _name: &str)2340     unsafe fn set_fence_name(&self, _fence: &mut Fence, _name: &str) {
2341         // TODO
2342     }
2343 
set_framebuffer_name(&self, _framebuffer: &mut Framebuffer, _name: &str)2344     unsafe fn set_framebuffer_name(&self, _framebuffer: &mut Framebuffer, _name: &str) {
2345         // TODO
2346     }
2347 
set_render_pass_name(&self, _render_pass: &mut RenderPass, _name: &str)2348     unsafe fn set_render_pass_name(&self, _render_pass: &mut RenderPass, _name: &str) {
2349         // TODO
2350     }
2351 
set_descriptor_set_name(&self, _descriptor_set: &mut DescriptorSet, _name: &str)2352     unsafe fn set_descriptor_set_name(&self, _descriptor_set: &mut DescriptorSet, _name: &str) {
2353         // TODO
2354     }
2355 
set_descriptor_set_layout_name( &self, _descriptor_set_layout: &mut DescriptorSetLayout, _name: &str, )2356     unsafe fn set_descriptor_set_layout_name(
2357         &self,
2358         _descriptor_set_layout: &mut DescriptorSetLayout,
2359         _name: &str,
2360     ) {
2361         // TODO
2362     }
2363 }
2364