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