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