1 //! Device 2 3 use com::WeakPtr; 4 use command_list::{CmdListType, CommandSignature, IndirectArgument}; 5 use descriptor::{CpuDescriptor, DescriptorHeapFlags, DescriptorHeapType, RenderTargetViewDesc}; 6 use heap::{Heap, HeapFlags, HeapProperties}; 7 use std::ops::Range; 8 use winapi::um::d3d12; 9 use winapi::Interface; 10 use {pso, query, queue}; 11 use { 12 Blob, CachedPSO, CommandAllocator, CommandQueue, D3DResult, DescriptorHeap, 13 Fence, GraphicsCommandList, NodeMask, PipelineState, QueryHeap, Resource, RootSignature, 14 Shader, TextureAddressMode, 15 }; 16 17 pub type Device = WeakPtr<d3d12::ID3D12Device>; 18 19 #[cfg(feature = "libloading")] 20 impl crate::D3D12Lib { create_device<I: Interface>( &self, adapter: WeakPtr<I>, feature_level: crate::FeatureLevel, ) -> libloading::Result<D3DResult<Device>>21 pub fn create_device<I: Interface>( 22 &self, 23 adapter: WeakPtr<I>, 24 feature_level: crate::FeatureLevel, 25 ) -> libloading::Result<D3DResult<Device>> { 26 type Fun = extern "system" fn( 27 *mut winapi::um::unknwnbase::IUnknown, 28 winapi::um::d3dcommon::D3D_FEATURE_LEVEL, 29 winapi::shared::guiddef::REFGUID, 30 *mut *mut winapi::ctypes::c_void, 31 ) -> crate::HRESULT; 32 33 let mut device = Device::null(); 34 let hr = unsafe { 35 let func: libloading::Symbol<Fun> = self.lib.get(b"D3D12CreateDevice")?; 36 func( 37 adapter.as_unknown() as *const _ as *mut _, 38 feature_level as _, 39 &d3d12::ID3D12Device::uuidof(), 40 device.mut_void(), 41 ) 42 }; 43 44 Ok((device, hr)) 45 } 46 } 47 48 impl Device { 49 #[cfg(feature = "implicit-link")] create<I: Interface>( adapter: WeakPtr<I>, feature_level: crate::FeatureLevel, ) -> D3DResult<Self>50 pub fn create<I: Interface>( 51 adapter: WeakPtr<I>, 52 feature_level: crate::FeatureLevel, 53 ) -> D3DResult<Self> { 54 let mut device = Device::null(); 55 let hr = unsafe { 56 d3d12::D3D12CreateDevice( 57 adapter.as_unknown() as *const _ as *mut _, 58 feature_level as _, 59 &d3d12::ID3D12Device::uuidof(), 60 device.mut_void(), 61 ) 62 }; 63 64 (device, hr) 65 } 66 create_heap( &self, size_in_bytes: u64, properties: HeapProperties, alignment: u64, flags: HeapFlags, ) -> D3DResult<Heap>67 pub fn create_heap( 68 &self, 69 size_in_bytes: u64, 70 properties: HeapProperties, 71 alignment: u64, 72 flags: HeapFlags, 73 ) -> D3DResult<Heap> { 74 let mut heap = Heap::null(); 75 76 let desc = d3d12::D3D12_HEAP_DESC { 77 SizeInBytes: size_in_bytes, 78 Properties: properties.0, 79 Alignment: alignment, 80 Flags: flags.bits(), 81 }; 82 83 let hr = unsafe { self.CreateHeap(&desc, &d3d12::ID3D12Heap::uuidof(), heap.mut_void()) }; 84 85 (heap, hr) 86 } 87 create_command_allocator(&self, list_type: CmdListType) -> D3DResult<CommandAllocator>88 pub fn create_command_allocator(&self, list_type: CmdListType) -> D3DResult<CommandAllocator> { 89 let mut allocator = CommandAllocator::null(); 90 let hr = unsafe { 91 self.CreateCommandAllocator( 92 list_type as _, 93 &d3d12::ID3D12CommandAllocator::uuidof(), 94 allocator.mut_void(), 95 ) 96 }; 97 98 (allocator, hr) 99 } 100 create_command_queue( &self, list_type: CmdListType, priority: queue::Priority, flags: queue::CommandQueueFlags, node_mask: NodeMask, ) -> D3DResult<CommandQueue>101 pub fn create_command_queue( 102 &self, 103 list_type: CmdListType, 104 priority: queue::Priority, 105 flags: queue::CommandQueueFlags, 106 node_mask: NodeMask, 107 ) -> D3DResult<CommandQueue> { 108 let desc = d3d12::D3D12_COMMAND_QUEUE_DESC { 109 Type: list_type as _, 110 Priority: priority as _, 111 Flags: flags.bits(), 112 NodeMask: node_mask, 113 }; 114 115 let mut queue = CommandQueue::null(); 116 let hr = unsafe { 117 self.CreateCommandQueue( 118 &desc, 119 &d3d12::ID3D12CommandQueue::uuidof(), 120 queue.mut_void(), 121 ) 122 }; 123 124 (queue, hr) 125 } 126 create_descriptor_heap( &self, num_descriptors: u32, heap_type: DescriptorHeapType, flags: DescriptorHeapFlags, node_mask: NodeMask, ) -> D3DResult<DescriptorHeap>127 pub fn create_descriptor_heap( 128 &self, 129 num_descriptors: u32, 130 heap_type: DescriptorHeapType, 131 flags: DescriptorHeapFlags, 132 node_mask: NodeMask, 133 ) -> D3DResult<DescriptorHeap> { 134 let desc = d3d12::D3D12_DESCRIPTOR_HEAP_DESC { 135 Type: heap_type as _, 136 NumDescriptors: num_descriptors, 137 Flags: flags.bits(), 138 NodeMask: node_mask, 139 }; 140 141 let mut heap = DescriptorHeap::null(); 142 let hr = unsafe { 143 self.CreateDescriptorHeap( 144 &desc, 145 &d3d12::ID3D12DescriptorHeap::uuidof(), 146 heap.mut_void(), 147 ) 148 }; 149 150 (heap, hr) 151 } 152 get_descriptor_increment_size(&self, heap_type: DescriptorHeapType) -> u32153 pub fn get_descriptor_increment_size(&self, heap_type: DescriptorHeapType) -> u32 { 154 unsafe { self.GetDescriptorHandleIncrementSize(heap_type as _) } 155 } 156 create_graphics_command_list( &self, list_type: CmdListType, allocator: CommandAllocator, initial: PipelineState, node_mask: NodeMask, ) -> D3DResult<GraphicsCommandList>157 pub fn create_graphics_command_list( 158 &self, 159 list_type: CmdListType, 160 allocator: CommandAllocator, 161 initial: PipelineState, 162 node_mask: NodeMask, 163 ) -> D3DResult<GraphicsCommandList> { 164 let mut command_list = GraphicsCommandList::null(); 165 let hr = unsafe { 166 self.CreateCommandList( 167 node_mask, 168 list_type as _, 169 allocator.as_mut_ptr(), 170 initial.as_mut_ptr(), 171 &d3d12::ID3D12GraphicsCommandList::uuidof(), 172 command_list.mut_void(), 173 ) 174 }; 175 176 (command_list, hr) 177 } 178 create_query_heap( &self, heap_ty: query::QueryHeapType, count: u32, node_mask: NodeMask, ) -> D3DResult<QueryHeap>179 pub fn create_query_heap( 180 &self, 181 heap_ty: query::QueryHeapType, 182 count: u32, 183 node_mask: NodeMask, 184 ) -> D3DResult<QueryHeap> { 185 let desc = d3d12::D3D12_QUERY_HEAP_DESC { 186 Type: heap_ty as _, 187 Count: count, 188 NodeMask: node_mask, 189 }; 190 191 let mut query_heap = QueryHeap::null(); 192 let hr = unsafe { 193 self.CreateQueryHeap( 194 &desc, 195 &d3d12::ID3D12QueryHeap::uuidof(), 196 query_heap.mut_void(), 197 ) 198 }; 199 200 (query_heap, hr) 201 } 202 create_graphics_pipeline_state( &self, _root_signature: RootSignature, _vs: Shader, _ps: Shader, _gs: Shader, _hs: Shader, _ds: Shader, _node_mask: NodeMask, _cached_pso: CachedPSO, _flags: pso::PipelineStateFlags, ) -> D3DResult<PipelineState>203 pub fn create_graphics_pipeline_state( 204 &self, 205 _root_signature: RootSignature, 206 _vs: Shader, 207 _ps: Shader, 208 _gs: Shader, 209 _hs: Shader, 210 _ds: Shader, 211 _node_mask: NodeMask, 212 _cached_pso: CachedPSO, 213 _flags: pso::PipelineStateFlags, 214 ) -> D3DResult<PipelineState> { 215 unimplemented!() 216 } 217 create_compute_pipeline_state( &self, root_signature: RootSignature, cs: Shader, node_mask: NodeMask, cached_pso: CachedPSO, flags: pso::PipelineStateFlags, ) -> D3DResult<PipelineState>218 pub fn create_compute_pipeline_state( 219 &self, 220 root_signature: RootSignature, 221 cs: Shader, 222 node_mask: NodeMask, 223 cached_pso: CachedPSO, 224 flags: pso::PipelineStateFlags, 225 ) -> D3DResult<PipelineState> { 226 let mut pipeline = PipelineState::null(); 227 let desc = d3d12::D3D12_COMPUTE_PIPELINE_STATE_DESC { 228 pRootSignature: root_signature.as_mut_ptr(), 229 CS: *cs, 230 NodeMask: node_mask, 231 CachedPSO: *cached_pso, 232 Flags: flags.bits(), 233 }; 234 235 let hr = unsafe { 236 self.CreateComputePipelineState( 237 &desc, 238 &d3d12::ID3D12PipelineState::uuidof(), 239 pipeline.mut_void(), 240 ) 241 }; 242 243 (pipeline, hr) 244 } 245 create_sampler( &self, sampler: CpuDescriptor, filter: d3d12::D3D12_FILTER, address_mode: TextureAddressMode, mip_lod_bias: f32, max_anisotropy: u32, comparison_op: d3d12::D3D12_COMPARISON_FUNC, border_color: [f32; 4], lod: Range<f32>, )246 pub fn create_sampler( 247 &self, 248 sampler: CpuDescriptor, 249 filter: d3d12::D3D12_FILTER, 250 address_mode: TextureAddressMode, 251 mip_lod_bias: f32, 252 max_anisotropy: u32, 253 comparison_op: d3d12::D3D12_COMPARISON_FUNC, 254 border_color: [f32; 4], 255 lod: Range<f32>, 256 ) { 257 let desc = d3d12::D3D12_SAMPLER_DESC { 258 Filter: filter, 259 AddressU: address_mode[0], 260 AddressV: address_mode[1], 261 AddressW: address_mode[2], 262 MipLODBias: mip_lod_bias, 263 MaxAnisotropy: max_anisotropy, 264 ComparisonFunc: comparison_op, 265 BorderColor: border_color, 266 MinLOD: lod.start, 267 MaxLOD: lod.end, 268 }; 269 270 unsafe { 271 self.CreateSampler(&desc, sampler); 272 } 273 } 274 create_root_signature( &self, blob: Blob, node_mask: NodeMask, ) -> D3DResult<RootSignature>275 pub fn create_root_signature( 276 &self, 277 blob: Blob, 278 node_mask: NodeMask, 279 ) -> D3DResult<RootSignature> { 280 let mut signature = RootSignature::null(); 281 let hr = unsafe { 282 self.CreateRootSignature( 283 node_mask, 284 blob.GetBufferPointer(), 285 blob.GetBufferSize(), 286 &d3d12::ID3D12RootSignature::uuidof(), 287 signature.mut_void(), 288 ) 289 }; 290 291 (signature, hr) 292 } 293 create_command_signature( &self, root_signature: RootSignature, arguments: &[IndirectArgument], stride: u32, node_mask: NodeMask, ) -> D3DResult<CommandSignature>294 pub fn create_command_signature( 295 &self, 296 root_signature: RootSignature, 297 arguments: &[IndirectArgument], 298 stride: u32, 299 node_mask: NodeMask, 300 ) -> D3DResult<CommandSignature> { 301 let mut signature = CommandSignature::null(); 302 let desc = d3d12::D3D12_COMMAND_SIGNATURE_DESC { 303 ByteStride: stride, 304 NumArgumentDescs: arguments.len() as _, 305 pArgumentDescs: arguments.as_ptr() as *const _, 306 NodeMask: node_mask, 307 }; 308 309 let hr = unsafe { 310 self.CreateCommandSignature( 311 &desc, 312 root_signature.as_mut_ptr(), 313 &d3d12::ID3D12CommandSignature::uuidof(), 314 signature.mut_void(), 315 ) 316 }; 317 318 (signature, hr) 319 } 320 create_render_target_view( &self, resource: Resource, desc: &RenderTargetViewDesc, descriptor: CpuDescriptor, )321 pub fn create_render_target_view( 322 &self, 323 resource: Resource, 324 desc: &RenderTargetViewDesc, 325 descriptor: CpuDescriptor, 326 ) { 327 unsafe { 328 self.CreateRenderTargetView(resource.as_mut_ptr(), &desc.0 as *const _, descriptor); 329 } 330 } 331 332 // TODO: interface not complete create_fence(&self, initial: u64) -> D3DResult<Fence>333 pub fn create_fence(&self, initial: u64) -> D3DResult<Fence> { 334 let mut fence = Fence::null(); 335 let hr = unsafe { 336 self.CreateFence( 337 initial, 338 d3d12::D3D12_FENCE_FLAG_NONE, 339 &d3d12::ID3D12Fence::uuidof(), 340 fence.mut_void(), 341 ) 342 }; 343 344 (fence, hr) 345 } 346 } 347