From e9192d9890718b378b0252cba26183299da6dc51 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Wed, 26 Oct 2022 22:27:42 -0400 Subject: [PATCH 01/22] Suballocate buffers --- Cargo.lock | 66 +++++++++++++++++++++++++ wgpu-hal/Cargo.toml | 3 +- wgpu-hal/src/dx12/device.rs | 99 +++++++++++++++++++++++++++---------- wgpu-hal/src/dx12/mod.rs | 2 + 4 files changed, 142 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index feb64e2729..57de2830bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -121,6 +130,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.9.3" @@ -993,6 +1017,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + [[package]] name = "gl_generator" version = "0.14.0" @@ -1105,6 +1135,19 @@ dependencies = [ "bitflags", ] +[[package]] +name = "gpu-allocator" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c29012e8b8c96f45a85dcdb07d1e121323719e9fdea38399aa63ec3d1974237e" +dependencies = [ + "backtrace", + "log", + "thiserror", + "winapi", + "windows", +] + [[package]] name = "gpu-descriptor" version = "0.2.3" @@ -1566,6 +1609,15 @@ dependencies = [ "cc", ] +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.15.0" @@ -2863,6 +2915,7 @@ dependencies = [ "glow", "glutin", "gpu-alloc", + "gpu-allocator", "gpu-descriptor", "js-sys", "khronos-egl", @@ -2945,6 +2998,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53b97a83176b369b0eb2fd8158d4ae215357d02df9d40c1e1bf1879c5482c80" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + [[package]] name = "windows-sys" version = "0.36.1" diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 5a0ce3afba..b7421ee3c9 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -27,7 +27,7 @@ metal = ["naga/msl-out", "block", "foreign-types"] vulkan = ["naga/spv-out", "ash", "gpu-alloc", "gpu-descriptor", "libloading", "smallvec"] gles = ["naga/glsl-out", "glow", "egl", "libloading"] dx11 = ["naga/hlsl-out", "native", "libloading", "winapi/d3d11", "winapi/d3d11_1", "winapi/d3d11_2", "winapi/d3d11sdklayers", "winapi/dxgi1_6"] -dx12 = ["naga/hlsl-out", "native", "bit-set", "range-alloc", "winapi/d3d12", "winapi/d3d12shader", "winapi/d3d12sdklayers", "winapi/dxgi1_6"] +dx12 = ["naga/hlsl-out", "native", "bit-set", "range-alloc", "winapi/d3d12", "winapi/d3d12shader", "winapi/d3d12sdklayers", "winapi/dxgi1_6", "gpu-allocator"] renderdoc = ["libloading", "renderdoc-sys"] emscripten = ["gles"] @@ -66,6 +66,7 @@ glow = { workspace = true, optional = true } # backend: Dx12 bit-set = { workspace = true, optional = true } +gpu-allocator = { version = "0.20",default_features = false, features = ["d3d12", "windows", "public-winapi"], optional = true } range-alloc = { workspace = true, optional = true } [dependencies.wgt] diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 92bbefef65..761414bd9c 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -12,6 +12,11 @@ use winapi::{ Interface, }; +use gpu_allocator::{ + d3d12::{winapi_d3d12::D3D12_RESOURCE_DESC, AllocationCreateDesc, ToWinapi, ToWindows}, + MemoryLocation, +}; + // this has to match Naga's HLSL backend, and also needs to be null-terminated const NAGA_LOCATION_SEMANTIC: &[u8] = b"LOC\0"; //TODO: find the exact value @@ -24,6 +29,18 @@ impl super::Device { private_caps: super::PrivateCapabilities, library: &Arc, ) -> Result { + let mem_allocator = { + let device = raw.as_ptr(); + + match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc { + device: device.as_windows().clone(), + debug_settings: Default::default(), + }) { + Ok(allocator) => allocator, + Err(e) => panic!("Failed to create d3d12 allocator, error: {}", e), + } + }; + let mut idle_fence = native::Fence::null(); let hr = unsafe { profiling::scope!("ID3D12Device::CreateFence"); @@ -165,6 +182,7 @@ impl super::Device { #[cfg(feature = "renderdoc")] render_doc: Default::default(), null_rtv_handle, + mem_allocator: Mutex::new(mem_allocator), }) } @@ -339,7 +357,7 @@ impl crate::Device for super::Device { size = ((size - 1) | align_mask) + 1; } - let raw_desc = d3d12::D3D12_RESOURCE_DESC { + let raw_desc = D3D12_RESOURCE_DESC { Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, Alignment: 0, Width: size, @@ -358,32 +376,49 @@ impl crate::Device for super::Device { let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); - let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { - Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, - CPUPageProperty: if is_cpu_read { - d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK - } else if is_cpu_write { - d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE - } else { - d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE - }, - MemoryPoolPreference: match self.private_caps.memory_architecture { - super::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { - d3d12::D3D12_MEMORY_POOL_L1 - } - _ => d3d12::D3D12_MEMORY_POOL_L0, - }, - CreationNodeMask: 0, - VisibleNodeMask: 0, + // let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { + // Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, + // CPUPageProperty: if is_cpu_read { + // d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK + // } else if is_cpu_write { + // d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE + // } else { + // d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE + // }, + // MemoryPoolPreference: match self.private_caps.memory_architecture { + // super::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { + // d3d12::D3D12_MEMORY_POOL_L1 + // } + // _ => d3d12::D3D12_MEMORY_POOL_L0, + // }, + // CreationNodeMask: 0, + // VisibleNodeMask: 0, + // }; + + // TODO: These are probably wrong? + let location = match (is_cpu_read, is_cpu_write) { + (true, true) => MemoryLocation::CpuToGpu, + (true, false) => MemoryLocation::GpuToCpu, + (false, true) => MemoryLocation::CpuToGpu, + (false, false) => MemoryLocation::GpuOnly, }; - let hr = self.raw.CreateCommittedResource( - &heap_properties, - if self.private_caps.heap_create_not_zeroed { - D3D12_HEAP_FLAG_CREATE_NOT_ZEROED - } else { - d3d12::D3D12_HEAP_FLAG_NONE - }, + let mut allocator = self.mem_allocator.lock(); + + let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( + allocator.device().as_winapi(), + &raw_desc, + "Example allocation", + location, + ); + + let allocation = allocator.allocate(&allocation_desc).unwrap(); + + // println!("allocation size: {}, expected size: {}", allocation.size(), size); + + let hr = self.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), &raw_desc, d3d12::D3D12_RESOURCE_STATE_COMMON, ptr::null(), @@ -397,10 +432,20 @@ impl crate::Device for super::Device { resource.SetName(cwstr.as_ptr()); } - Ok(super::Buffer { resource, size }) + Ok(super::Buffer { + resource, + size, + allocation: Some(allocation), + }) } - unsafe fn destroy_buffer(&self, buffer: super::Buffer) { + unsafe fn destroy_buffer(&self, mut buffer: super::Buffer) { buffer.resource.destroy(); + if let Some(alloc) = buffer.allocation.take() { + match self.mem_allocator.lock().free(alloc) { + Ok(_) => (), + Err(e) => panic!("failed to destroy dx12 buffer, {}", e), + }; + } } unsafe fn map_buffer( &self, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 6f9f18b6ca..46f938701d 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -233,6 +233,7 @@ pub struct Device { #[cfg(feature = "renderdoc")] render_doc: crate::auxil::renderdoc::RenderDoc, null_rtv_handle: descriptor::Handle, + mem_allocator: Mutex, } unsafe impl Send for Device {} @@ -368,6 +369,7 @@ unsafe impl Sync for CommandBuffer {} pub struct Buffer { resource: native::Resource, size: wgt::BufferAddress, + allocation: Option, } unsafe impl Send for Buffer {} From a9d5189ff4023e2e9c02e434caf5a291de38681e Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Tue, 1 Nov 2022 02:25:44 -0400 Subject: [PATCH 02/22] Error handling stub Error handling stub --- wgpu-hal/src/dx12/device.rs | 5 +---- wgpu-hal/src/dx12/mod.rs | 13 +++++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 761414bd9c..4a08e8d7c5 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -411,10 +411,7 @@ impl crate::Device for super::Device { "Example allocation", location, ); - - let allocation = allocator.allocate(&allocation_desc).unwrap(); - - // println!("allocation size: {}, expected size: {}", allocation.size(), size); + let allocation = allocator.allocate(&allocation_desc)?; let hr = self.raw.CreatePlacedResource( allocation.heap().as_winapi() as *mut _, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 46f938701d..0337d8c2a3 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -816,3 +816,16 @@ impl crate::Queue for Queue { (1_000_000_000.0 / frequency as f64) as f32 } } + +impl From for crate::DeviceError { + fn from(result: gpu_allocator::AllocationError) -> Self { + match result { + gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, + gpu_allocator::AllocationError::FailedToMap(_) => todo!(), + gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => todo!(), + gpu_allocator::AllocationError::InvalidAllocationCreateDesc => todo!(), + gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(_) => todo!(), + gpu_allocator::AllocationError::Internal(e) => panic!("gpu-allocator internal error: {}", e), + } + } +} \ No newline at end of file From 1868f26b649f2cde3180b6210b3bb982a728164b Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Tue, 1 Nov 2022 02:29:15 -0400 Subject: [PATCH 03/22] Suballocate Textures --- wgpu-hal/src/dx12/device.rs | 43 +++++++++++++++++++++---------------- wgpu-hal/src/dx12/mod.rs | 2 ++ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 4a08e8d7c5..340a6b6119 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -330,6 +330,7 @@ impl super::Device { size, mip_level_count, sample_count, + allocation: None, } } } @@ -472,7 +473,7 @@ impl crate::Device for super::Device { ) -> Result { let mut resource = native::Resource::null(); - let raw_desc = d3d12::D3D12_RESOURCE_DESC { + let raw_desc = D3D12_RESOURCE_DESC { Dimension: conv::map_texture_dimension(desc.dimension), Alignment: 0, Width: desc.size.width as u64, @@ -501,24 +502,20 @@ impl crate::Device for super::Device { Flags: conv::map_texture_usage_to_resource_flags(desc.usage), }; - let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { - Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, - CPUPageProperty: d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, - MemoryPoolPreference: match self.private_caps.memory_architecture { - super::MemoryArchitecture::NonUnified => d3d12::D3D12_MEMORY_POOL_L1, - super::MemoryArchitecture::Unified { .. } => d3d12::D3D12_MEMORY_POOL_L0, - }, - CreationNodeMask: 0, - VisibleNodeMask: 0, - }; + // TODO: What memory location should the texture be stored in? + let location = MemoryLocation::Unknown; + let mut allocator = self.mem_allocator.lock(); + let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( + allocator.device().as_winapi(), + &raw_desc, + "Example allocation", + location, + ); + let allocation = allocator.allocate(&allocation_desc)?; - let hr = self.raw.CreateCommittedResource( - &heap_properties, - if self.private_caps.heap_create_not_zeroed { - D3D12_HEAP_FLAG_CREATE_NOT_ZEROED - } else { - d3d12::D3D12_HEAP_FLAG_NONE - }, + let hr = self.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), &raw_desc, d3d12::D3D12_RESOURCE_STATE_COMMON, ptr::null(), // clear value @@ -539,10 +536,18 @@ impl crate::Device for super::Device { size: desc.size, mip_level_count: desc.mip_level_count, sample_count: desc.sample_count, + allocation: Some(allocation), }) } - unsafe fn destroy_texture(&self, texture: super::Texture) { + + unsafe fn destroy_texture(&self, mut texture: super::Texture) { texture.resource.destroy(); + if let Some(alloc) = texture.allocation.take() { + match self.mem_allocator.lock().free(alloc) { + Ok(_) => (), + Err(e) => panic!("failed to destroy dx12 buffer, {}", e), + }; + } } unsafe fn create_texture_view( diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 0337d8c2a3..11a26d1e1f 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -396,6 +396,7 @@ pub struct Texture { size: wgt::Extent3d, mip_level_count: u32, sample_count: u32, + allocation: Option, } unsafe impl Send for Texture {} @@ -753,6 +754,7 @@ impl crate::Surface for Surface { size: sc.size, mip_level_count: 1, sample_count: 1, + allocation: None, }; Ok(Some(crate::AcquiredSurfaceTexture { texture, From baea8319c6a7fb69542ad191442c08a9ff6b3887 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Tue, 1 Nov 2022 02:29:33 -0400 Subject: [PATCH 04/22] cleanup --- wgpu-hal/src/dx12/device.rs | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 340a6b6119..500a447aae 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -55,7 +55,7 @@ impl super::Device { let mut zero_buffer = native::Resource::null(); unsafe { - let raw_desc = d3d12::D3D12_RESOURCE_DESC { + let raw_desc = D3D12_RESOURCE_DESC { Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, Alignment: 0, Width: super::ZERO_BUFFER_SIZE, @@ -360,6 +360,7 @@ impl crate::Device for super::Device { let raw_desc = D3D12_RESOURCE_DESC { Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, + // TODO: Alignment, see https://www.asawicki.info/news_1726_secrets_of_direct3d_12_resource_alignment Alignment: 0, Width: size, Height: 1, @@ -376,26 +377,6 @@ impl crate::Device for super::Device { let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); - - // let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { - // Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, - // CPUPageProperty: if is_cpu_read { - // d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK - // } else if is_cpu_write { - // d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE - // } else { - // d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE - // }, - // MemoryPoolPreference: match self.private_caps.memory_architecture { - // super::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { - // d3d12::D3D12_MEMORY_POOL_L1 - // } - // _ => d3d12::D3D12_MEMORY_POOL_L0, - // }, - // CreationNodeMask: 0, - // VisibleNodeMask: 0, - // }; - // TODO: These are probably wrong? let location = match (is_cpu_read, is_cpu_write) { (true, true) => MemoryLocation::CpuToGpu, @@ -405,7 +386,6 @@ impl crate::Device for super::Device { }; let mut allocator = self.mem_allocator.lock(); - let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( allocator.device().as_winapi(), &raw_desc, @@ -437,10 +417,12 @@ impl crate::Device for super::Device { }) } unsafe fn destroy_buffer(&self, mut buffer: super::Buffer) { + // TODO: Destroy or Release here? buffer.resource.destroy(); if let Some(alloc) = buffer.allocation.take() { match self.mem_allocator.lock().free(alloc) { Ok(_) => (), + // TODO: Don't panic here Err(e) => panic!("failed to destroy dx12 buffer, {}", e), }; } @@ -451,6 +433,7 @@ impl crate::Device for super::Device { range: crate::MemoryRange, ) -> Result { let mut ptr = ptr::null_mut(); + // TODO: 0 for subresource should be fine here until unmap buffer is subresource aware? let hr = (*buffer.resource).Map(0, ptr::null(), &mut ptr); hr.into_device_result("Map buffer")?; Ok(crate::BufferMapping { From f9e44f2a178cf0706d401199e4e2765938712329 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Tue, 1 Nov 2022 02:49:46 -0400 Subject: [PATCH 05/22] cargo.toml workspace --- Cargo.toml | 1 + wgpu-hal/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1eb3768f0e..1a9af7b0ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,6 +96,7 @@ android_system_properties = "0.1.1" # DX dependencies bit-set = "0.5" +gpu-allocator = { version = "0.20",default_features = false, features = ["d3d12", "windows", "public-winapi"] } native = { package = "d3d12", version = "0.5.0" } range-alloc = "0.1" winapi = "0.3" diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index b7421ee3c9..e4fef97bfb 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -66,7 +66,7 @@ glow = { workspace = true, optional = true } # backend: Dx12 bit-set = { workspace = true, optional = true } -gpu-allocator = { version = "0.20",default_features = false, features = ["d3d12", "windows", "public-winapi"], optional = true } +gpu-allocator = { workspace = true, optional = true } range-alloc = { workspace = true, optional = true } [dependencies.wgt] From 34c42b4e0d89e97dbf56f5228bcf53ec653bba8c Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Tue, 1 Nov 2022 17:04:23 -0400 Subject: [PATCH 06/22] Appease CI, cast ptr instead of as --- wgpu-hal/src/dx12/adapter.rs | 2 +- wgpu-hal/src/dx12/device.rs | 9 +++++---- wgpu-hal/src/dx12/mod.rs | 8 +++++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index edbda11d2f..3147e1af7c 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -161,7 +161,7 @@ impl super::Adapter { } else { super::MemoryArchitecture::NonUnified }, - heap_create_not_zeroed: false, //TODO: winapi support for Options7 + _heap_create_not_zeroed: false, //TODO: winapi support for Options7 }; // Theoretically vram limited, but in practice 2^20 is the limit diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 500a447aae..3bf9dae512 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -19,8 +19,9 @@ use gpu_allocator::{ // this has to match Naga's HLSL backend, and also needs to be null-terminated const NAGA_LOCATION_SEMANTIC: &[u8] = b"LOC\0"; -//TODO: find the exact value -const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; +// TODO: find the exact value +// TODO: figure out if this is even needed? +const _D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; impl super::Device { pub(super) fn new( @@ -433,11 +434,11 @@ impl crate::Device for super::Device { range: crate::MemoryRange, ) -> Result { let mut ptr = ptr::null_mut(); - // TODO: 0 for subresource should be fine here until unmap buffer is subresource aware? + // TODO: 0 for subresource should be fine here until map and unmap buffer is subresource aware? let hr = (*buffer.resource).Map(0, ptr::null(), &mut ptr); hr.into_device_result("Map buffer")?; Ok(crate::BufferMapping { - ptr: ptr::NonNull::new(ptr.offset(range.start as isize) as *mut _).unwrap(), + ptr: ptr::NonNull::new(ptr.offset(range.start as isize).cast::()).unwrap(), //TODO: double-check this. Documentation is a bit misleading - // it implies that Map/Unmap is needed to invalidate/flush memory. is_coherent: true, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 11a26d1e1f..129eda5500 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -152,7 +152,7 @@ struct PrivateCapabilities { #[allow(unused)] heterogeneous_resource_heaps: bool, memory_architecture: MemoryArchitecture, - heap_create_not_zeroed: bool, + _heap_create_not_zeroed: bool, } #[derive(Default)] @@ -827,7 +827,9 @@ impl From for crate::DeviceError { gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => todo!(), gpu_allocator::AllocationError::InvalidAllocationCreateDesc => todo!(), gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(_) => todo!(), - gpu_allocator::AllocationError::Internal(e) => panic!("gpu-allocator internal error: {}", e), + gpu_allocator::AllocationError::Internal(e) => { + panic!("gpu-allocator internal error: {}", e) + } } } -} \ No newline at end of file +} From 029318cf8d9ea5f9d8dea5f8d87446156e4ac1d3 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 21 Nov 2022 16:55:09 -0500 Subject: [PATCH 07/22] unsafe_op_in_unsafe_fn --- wgpu-hal/src/dx12/device.rs | 49 ++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index bfe5abd365..3b1e447497 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -395,15 +395,17 @@ impl crate::Device for super::Device { ); let allocation = allocator.allocate(&allocation_desc)?; - let hr = self.raw.CreatePlacedResource( - allocation.heap().as_winapi() as *mut _, - allocation.offset(), - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ); + let hr = unsafe { + self.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; hr.into_device_result("Buffer creation")?; if let Some(label) = desc.label { @@ -419,7 +421,7 @@ impl crate::Device for super::Device { } unsafe fn destroy_buffer(&self, mut buffer: super::Buffer) { // TODO: Destroy or Release here? - buffer.resource.destroy(); + unsafe { buffer.resource.destroy() }; if let Some(alloc) = buffer.allocation.take() { match self.mem_allocator.lock().free(alloc) { Ok(_) => (), @@ -435,10 +437,11 @@ impl crate::Device for super::Device { ) -> Result { let mut ptr = ptr::null_mut(); // TODO: 0 for subresource should be fine here until map and unmap buffer is subresource aware? - let hr = (*buffer.resource).Map(0, ptr::null(), &mut ptr); + let hr = unsafe { (*buffer.resource).Map(0, ptr::null(), &mut ptr) }; hr.into_device_result("Map buffer")?; Ok(crate::BufferMapping { - ptr: ptr::NonNull::new(ptr.offset(range.start as isize).cast::()).unwrap(), + ptr: ptr::NonNull::new(unsafe { ptr.offset(range.start as isize).cast::() }) + .unwrap(), //TODO: double-check this. Documentation is a bit misleading - // it implies that Map/Unmap is needed to invalidate/flush memory. is_coherent: true, @@ -497,15 +500,17 @@ impl crate::Device for super::Device { ); let allocation = allocator.allocate(&allocation_desc)?; - let hr = self.raw.CreatePlacedResource( - allocation.heap().as_winapi() as *mut _, - allocation.offset(), - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), // clear value - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ); + let hr = unsafe { + self.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), // clear value + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; hr.into_device_result("Texture creation")?; if let Some(label) = desc.label { @@ -525,7 +530,7 @@ impl crate::Device for super::Device { } unsafe fn destroy_texture(&self, mut texture: super::Texture) { - texture.resource.destroy(); + unsafe { texture.resource.destroy() }; if let Some(alloc) = texture.allocation.take() { match self.mem_allocator.lock().free(alloc) { Ok(_) => (), From a782dfc95e528c4302c9782c70175a3bbd0ae33c Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 21 Nov 2022 18:11:50 -0500 Subject: [PATCH 08/22] dx12 handle gpu-allocator errors --- wgpu-hal/src/dx12/mod.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index b17477c077..b1d0365b6c 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -44,6 +44,7 @@ mod view; use crate::auxil::{self, dxgi::result::HResult as _}; use arrayvec::ArrayVec; +use log::error; use parking_lot::Mutex; use std::{ffi, fmt, mem, num::NonZeroU32, sync::Arc}; use winapi::{ @@ -836,12 +837,28 @@ impl From for crate::DeviceError { fn from(result: gpu_allocator::AllocationError) -> Self { match result { gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, - gpu_allocator::AllocationError::FailedToMap(_) => todo!(), - gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => todo!(), - gpu_allocator::AllocationError::InvalidAllocationCreateDesc => todo!(), - gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(_) => todo!(), + gpu_allocator::AllocationError::FailedToMap(e) => { + error!("DX12 gpu-allocator: Failed to map: {}", e); + Self::Lost + } + gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => { + error!("DX12 gpu-allocator: No Compatible Memory Type Found"); + Self::Lost + } + gpu_allocator::AllocationError::InvalidAllocationCreateDesc => { + error!("DX12 gpu-allocator: Invalid Allocation Creation Description"); + Self::Lost + } + gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => { + error!( + "DX12 gpu-allocator: Invalid Allocator Creation Description: {}", + e + ); + Self::Lost + } gpu_allocator::AllocationError::Internal(e) => { - panic!("gpu-allocator internal error: {}", e) + error!("DX12 gpu-allocator: Internal Error: {}", e); + Self::Lost } } } From 2ee1a415449065709da8227f5493bbf0447bace8 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Sat, 26 Nov 2022 02:42:11 -0500 Subject: [PATCH 09/22] Stick gpu-allocator behind a feature until #3207 lands --- wgpu-hal/Cargo.toml | 4 +- wgpu-hal/src/dx12/adapter.rs | 2 +- wgpu-hal/src/dx12/device.rs | 208 ++++++++++++++++++++++++++++++++++- wgpu-hal/src/dx12/mod.rs | 11 +- 4 files changed, 220 insertions(+), 5 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 7c2aec7d03..e7bc1a6441 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -27,7 +27,9 @@ metal = ["naga/msl-out", "block", "foreign-types"] vulkan = ["naga/spv-out", "ash", "gpu-alloc", "gpu-descriptor", "libloading", "smallvec"] gles = ["naga/glsl-out", "glow", "egl", "libloading"] dx11 = ["naga/hlsl-out", "native", "libloading", "winapi/d3d11", "winapi/d3d11_1", "winapi/d3d11_2", "winapi/d3d11sdklayers", "winapi/dxgi1_6"] -dx12 = ["naga/hlsl-out", "native", "bit-set", "range-alloc", "winapi/d3d12", "winapi/d3d12shader", "winapi/d3d12sdklayers", "winapi/dxgi1_6", "gpu-allocator"] +dx12 = ["naga/hlsl-out", "native", "bit-set", "range-alloc", "winapi/d3d12", "winapi/d3d12shader", "winapi/d3d12sdklayers", "winapi/dxgi1_6"] +# TODO: This is a separate feature until Mozilla okays windows-rs, see https://github.com/gfx-rs/wgpu/issues/3207 for the tracking issue. +windows_rs = ["gpu-allocator"] renderdoc = ["libloading", "renderdoc-sys"] emscripten = ["gles"] diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index b216071b4e..236fec49c3 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -163,7 +163,7 @@ impl super::Adapter { } else { super::MemoryArchitecture::NonUnified }, - _heap_create_not_zeroed: false, //TODO: winapi support for Options7 + heap_create_not_zeroed: false, //TODO: winapi support for Options7 }; // Theoretically vram limited, but in practice 2^20 is the limit diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 3b1e447497..c209386b66 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -12,6 +12,10 @@ use winapi::{ Interface, }; +#[cfg(not(feature = "windows_rs"))] +use winapi::um::d3d12::D3D12_RESOURCE_DESC; + +#[cfg(feature = "windows_rs")] use gpu_allocator::{ d3d12::{winapi_d3d12::D3D12_RESOURCE_DESC, AllocationCreateDesc, ToWinapi, ToWindows}, MemoryLocation, @@ -21,7 +25,8 @@ use gpu_allocator::{ const NAGA_LOCATION_SEMANTIC: &[u8] = b"LOC\0"; // TODO: find the exact value // TODO: figure out if this is even needed? -const _D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; +#[allow(unused)] // TODO: Exists until windows-rs is standard, then it can probably be removed? +const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; impl super::Device { pub(super) fn new( @@ -30,6 +35,7 @@ impl super::Device { private_caps: super::PrivateCapabilities, library: &Arc, ) -> Result { + #[cfg(feature = "windows_rs")] let mem_allocator = { let device = raw.as_ptr(); @@ -183,6 +189,7 @@ impl super::Device { #[cfg(feature = "renderdoc")] render_doc: Default::default(), null_rtv_handle, + #[cfg(feature = "windows_rs")] mem_allocator: Mutex::new(mem_allocator), }) } @@ -331,6 +338,7 @@ impl super::Device { size, mip_level_count, sample_count, + #[cfg(feature = "windows_rs")] allocation: None, } } @@ -348,6 +356,7 @@ impl crate::Device for super::Device { unsafe { queue.raw.destroy() }; } + #[cfg(feature = "windows_rs")] unsafe fn create_buffer( &self, desc: &crate::BufferDescriptor, @@ -419,6 +428,83 @@ impl crate::Device for super::Device { allocation: Some(allocation), }) } + + #[cfg(not(feature = "windows_rs"))] + unsafe fn create_buffer( + &self, + desc: &crate::BufferDescriptor, + ) -> Result { + let mut resource = native::Resource::null(); + let mut size = desc.size; + if desc.usage.contains(crate::BufferUses::UNIFORM) { + let align_mask = d3d12::D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT as u64 - 1; + size = ((size - 1) | align_mask) + 1; + } + + let raw_desc = D3D12_RESOURCE_DESC { + Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, + Alignment: 0, + Width: size, + Height: 1, + DepthOrArraySize: 1, + MipLevels: 1, + Format: dxgiformat::DXGI_FORMAT_UNKNOWN, + SampleDesc: dxgitype::DXGI_SAMPLE_DESC { + Count: 1, + Quality: 0, + }, + Layout: d3d12::D3D12_TEXTURE_LAYOUT_ROW_MAJOR, + Flags: conv::map_buffer_usage_to_resource_flags(desc.usage), + }; + + let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); + let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); + + let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { + Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, + CPUPageProperty: if is_cpu_read { + d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK + } else if is_cpu_write { + d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE + } else { + d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE + }, + MemoryPoolPreference: match self.private_caps.memory_architecture { + super::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { + d3d12::D3D12_MEMORY_POOL_L1 + } + _ => d3d12::D3D12_MEMORY_POOL_L0, + }, + CreationNodeMask: 0, + VisibleNodeMask: 0, + }; + + let hr = unsafe { + self.raw.CreateCommittedResource( + &heap_properties, + if self.private_caps.heap_create_not_zeroed { + D3D12_HEAP_FLAG_CREATE_NOT_ZEROED + } else { + d3d12::D3D12_HEAP_FLAG_NONE + }, + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; + + hr.into_device_result("Buffer creation")?; + if let Some(label) = desc.label { + let cwstr = conv::map_label(label); + unsafe { resource.SetName(cwstr.as_ptr()) }; + } + + Ok(super::Buffer { resource, size }) + } + + #[cfg(feature = "windows_rs")] unsafe fn destroy_buffer(&self, mut buffer: super::Buffer) { // TODO: Destroy or Release here? unsafe { buffer.resource.destroy() }; @@ -430,6 +516,13 @@ impl crate::Device for super::Device { }; } } + + #[cfg(not(feature = "windows_rs"))] + unsafe fn destroy_buffer(&self, buffer: super::Buffer) { + unsafe { buffer.resource.destroy() }; + } + + #[cfg(feature = "windows_rs")] unsafe fn map_buffer( &self, buffer: &super::Buffer, @@ -447,13 +540,41 @@ impl crate::Device for super::Device { is_coherent: true, }) } + + #[cfg(not(feature = "windows_rs"))] + unsafe fn map_buffer( + &self, + buffer: &super::Buffer, + range: crate::MemoryRange, + ) -> Result { + let mut ptr = ptr::null_mut(); + let hr = unsafe { (*buffer.resource).Map(0, ptr::null(), &mut ptr) }; + hr.into_device_result("Map buffer")?; + Ok(crate::BufferMapping { + ptr: ptr::NonNull::new(unsafe { ptr.offset(range.start as isize).cast::() }) + .unwrap(), + //TODO: double-check this. Documentation is a bit misleading - + // it implies that Map/Unmap is needed to invalidate/flush memory. + is_coherent: true, + }) + } + + #[cfg(feature = "windows_rs")] + unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> { + unsafe { (*buffer.resource).Unmap(0, ptr::null()) }; + Ok(()) + } + + #[cfg(not(feature = "windows_rs"))] unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> { unsafe { (*buffer.resource).Unmap(0, ptr::null()) }; Ok(()) } + unsafe fn flush_mapped_ranges(&self, _buffer: &super::Buffer, _ranges: I) {} unsafe fn invalidate_mapped_ranges(&self, _buffer: &super::Buffer, _ranges: I) {} + #[cfg(feature = "windows_rs")] unsafe fn create_texture( &self, desc: &crate::TextureDescriptor, @@ -529,6 +650,86 @@ impl crate::Device for super::Device { }) } + #[cfg(not(feature = "windows_rs"))] + unsafe fn create_texture( + &self, + desc: &crate::TextureDescriptor, + ) -> Result { + let mut resource = native::Resource::null(); + + let raw_desc = D3D12_RESOURCE_DESC { + Dimension: conv::map_texture_dimension(desc.dimension), + Alignment: 0, + Width: desc.size.width as u64, + Height: desc.size.height, + DepthOrArraySize: desc.size.depth_or_array_layers as u16, + MipLevels: desc.mip_level_count as u16, + Format: if crate::FormatAspects::from(desc.format).contains(crate::FormatAspects::COLOR) + || !desc.usage.intersects( + crate::TextureUses::RESOURCE + | crate::TextureUses::STORAGE_READ + | crate::TextureUses::STORAGE_READ_WRITE, + ) { + auxil::dxgi::conv::map_texture_format(desc.format) + } else { + // This branch is needed if it's a depth texture, and it's ever needed to be viewed as SRV or UAV, + // because then we'd create a non-depth format view of it. + // Note: we can skip this branch if + // `D3D12_FEATURE_D3D12_OPTIONS3::CastingFullyTypedFormatSupported` + auxil::dxgi::conv::map_texture_format_depth_typeless(desc.format) + }, + SampleDesc: dxgitype::DXGI_SAMPLE_DESC { + Count: desc.sample_count, + Quality: 0, + }, + Layout: d3d12::D3D12_TEXTURE_LAYOUT_UNKNOWN, + Flags: conv::map_texture_usage_to_resource_flags(desc.usage), + }; + + let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { + Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, + CPUPageProperty: d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, + MemoryPoolPreference: match self.private_caps.memory_architecture { + super::MemoryArchitecture::NonUnified => d3d12::D3D12_MEMORY_POOL_L1, + super::MemoryArchitecture::Unified { .. } => d3d12::D3D12_MEMORY_POOL_L0, + }, + CreationNodeMask: 0, + VisibleNodeMask: 0, + }; + + let hr = unsafe { + self.raw.CreateCommittedResource( + &heap_properties, + if self.private_caps.heap_create_not_zeroed { + D3D12_HEAP_FLAG_CREATE_NOT_ZEROED + } else { + d3d12::D3D12_HEAP_FLAG_NONE + }, + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), // clear value + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; + + hr.into_device_result("Texture creation")?; + if let Some(label) = desc.label { + let cwstr = conv::map_label(label); + unsafe { resource.SetName(cwstr.as_ptr()) }; + } + + Ok(super::Texture { + resource, + format: desc.format, + dimension: desc.dimension, + size: desc.size, + mip_level_count: desc.mip_level_count, + sample_count: desc.sample_count, + }) + } + + #[cfg(feature = "windows_rs")] unsafe fn destroy_texture(&self, mut texture: super::Texture) { unsafe { texture.resource.destroy() }; if let Some(alloc) = texture.allocation.take() { @@ -539,6 +740,11 @@ impl crate::Device for super::Device { } } + #[cfg(not(feature = "windows_rs"))] + unsafe fn destroy_texture(&self, texture: super::Texture) { + unsafe { texture.resource.destroy() }; + } + unsafe fn create_texture_view( &self, texture: &super::Texture, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index b1d0365b6c..ff91bf244e 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -44,7 +44,6 @@ mod view; use crate::auxil::{self, dxgi::result::HResult as _}; use arrayvec::ArrayVec; -use log::error; use parking_lot::Mutex; use std::{ffi, fmt, mem, num::NonZeroU32, sync::Arc}; use winapi::{ @@ -153,7 +152,8 @@ struct PrivateCapabilities { #[allow(unused)] heterogeneous_resource_heaps: bool, memory_architecture: MemoryArchitecture, - _heap_create_not_zeroed: bool, + #[allow(unused)] // TODO: Exists until windows-rs is standard, then it can probably be removed? + heap_create_not_zeroed: bool, } #[derive(Default)] @@ -238,6 +238,7 @@ pub struct Device { #[cfg(feature = "renderdoc")] render_doc: crate::auxil::renderdoc::RenderDoc, null_rtv_handle: descriptor::Handle, + #[cfg(feature = "windows_rs")] mem_allocator: Mutex, } @@ -374,6 +375,7 @@ unsafe impl Sync for CommandBuffer {} pub struct Buffer { resource: native::Resource, size: wgt::BufferAddress, + #[cfg(feature = "windows_rs")] allocation: Option, } @@ -401,6 +403,7 @@ pub struct Texture { size: wgt::Extent3d, mip_level_count: u32, sample_count: u32, + #[cfg(feature = "windows_rs")] allocation: Option, } @@ -768,6 +771,7 @@ impl crate::Surface for Surface { size: sc.size, mip_level_count: 1, sample_count: 1, + #[cfg(feature = "windows_rs")] allocation: None, }; Ok(Some(crate::AcquiredSurfaceTexture { @@ -833,8 +837,11 @@ impl crate::Queue for Queue { } } +#[cfg(feature = "windows_rs")] impl From for crate::DeviceError { fn from(result: gpu_allocator::AllocationError) -> Self { + use log::error; + match result { gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, gpu_allocator::AllocationError::FailedToMap(e) => { From c24ecf85d9494517c4c50e0d173ab7397a0140e5 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Sat, 26 Nov 2022 02:42:38 -0500 Subject: [PATCH 10/22] gpu-allocator 0.21 --- Cargo.lock | 382 +++++++++++++++++++++++++++++++++-------------------- Cargo.toml | 2 +- 2 files changed, 242 insertions(+), 142 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57de2830bf..c091b3f58f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "once_cell", "version_check", ] @@ -48,9 +48,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "arrayref" @@ -84,18 +84,28 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" dependencies = [ + "async-lock", "async-task", "concurrent-queue", "fastrand", "futures-lite", - "once_cell", "slab", ] +[[package]] +name = "async-lock" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +dependencies = [ + "event-listener", + "futures-lite", +] + [[package]] name = "async-task" version = "4.3.0" @@ -104,9 +114,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", @@ -140,7 +150,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.5.4", "object", "rustc-demangle", ] @@ -163,9 +173,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64-simd" @@ -215,24 +225,24 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytemuck" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9e1f5fa78f69496407a27ae9ed989e3c3b072310286f5ef385525e4cbc24a9" +checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4" dependencies = [ "proc-macro2", "quote", @@ -251,20 +261,14 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" - [[package]] name = "calloop" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22a6a8f622f797120d452c630b0ab12e1331a1a753e2039ce7868d4ac77b4ee" +checksum = "5bcf530afb40e45e14440701e5e996d7fd139e84a912a4d83a8d6a0fb3e58663" dependencies = [ "log", - "nix", + "nix 0.25.0", "slotmap", "thiserror", "vec_map", @@ -283,9 +287,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.73" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" [[package]] name = "cfg-if" @@ -310,18 +314,18 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.48" +version = "0.1.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" dependencies = [ "cc", ] [[package]] name = "cocoa" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" dependencies = [ "bitflags", "block", @@ -360,11 +364,11 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "1.2.4" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" +checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" dependencies = [ - "cache-padded", + "crossbeam-utils", ] [[package]] @@ -455,11 +459,20 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossfont" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66b1c1979c4362323f03ab6bf7fb522902bfc418e0c37319ab347f9561d980f" +checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45" dependencies = [ "cocoa", "core-foundation", @@ -736,9 +749,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -747,6 +760,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "expat-sys" version = "2.1.6" @@ -779,7 +798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.5.4", ] [[package]] @@ -873,9 +892,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -888,9 +907,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -898,15 +917,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-executor" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" dependencies = [ "futures-core", "futures-task", @@ -915,9 +934,9 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" dependencies = [ "futures-core", "lock_api", @@ -926,9 +945,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-lite" @@ -947,9 +966,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ "proc-macro2", "quote", @@ -958,21 +977,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -1008,9 +1027,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -1137,9 +1156,9 @@ dependencies = [ [[package]] name = "gpu-allocator" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c29012e8b8c96f45a85dcdb07d1e121323719e9fdea38399aa63ec3d1974237e" +checksum = "434618454f74b63f9b39328298097256977c41ea0ba9d75a47238b77790b6163" dependencies = [ "backtrace", "log", @@ -1237,9 +1256,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -1260,9 +1279,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jni-sys" @@ -1310,15 +1329,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.134" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "libloading" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if", "winapi", @@ -1360,9 +1379,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" +checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" dependencies = [ "libc", ] @@ -1405,16 +1424,25 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1496,9 +1524,9 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.4.0" +version = "0.4.0+25.0.8775105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d83ec9c63ec5bf950200a8e508bdad6659972187b625469f58ef8c08e29046" +checksum = "f74ddd54b7da8d38d399faf43472ac9759f1a028a45c83154bff603e0f56385a" dependencies = [ "jni-sys", ] @@ -1515,6 +1543,19 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nix" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "noise" version = "0.7.0" @@ -1555,9 +1596,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ "hermit-abi", "libc", @@ -1620,9 +1661,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "osmesa-sys" @@ -1657,7 +1698,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.3", + "parking_lot_core 0.9.4", ] [[package]] @@ -1676,15 +1717,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1743,9 +1784,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "player" @@ -1763,14 +1804,14 @@ dependencies = [ [[package]] name = "png" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" dependencies = [ "bitflags", "crc32fast", "flate2", - "miniz_oxide", + "miniz_oxide 0.6.2", ] [[package]] @@ -1790,9 +1831,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" @@ -1807,18 +1848,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f61dcf0b917cd75d4521d7343d1ffff3d1583054133c9b5cbea3375c703c40d" +checksum = "74605f360ce573babfe43964cbe520294dcb081afbf8c108fc6e23036b4da2df" [[package]] name = "quote" @@ -1914,9 +1955,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -1925,9 +1966,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -1950,7 +1991,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "bitflags", "serde", ] @@ -2015,9 +2056,9 @@ checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" @@ -2027,9 +2068,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sctk-adwaita" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04b7c47a572f73de28bee5b5060d085b42b6ce1e4ee2b49c956ea7b25e94b6f0" +checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" dependencies = [ "crossfont", "log", @@ -2060,9 +2101,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] @@ -2078,9 +2119,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", @@ -2089,9 +2130,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" dependencies = [ "indexmap", "itoa", @@ -2206,7 +2247,7 @@ dependencies = [ "lazy_static", "log", "memmap2", - "nix", + "nix 0.24.2", "pkg-config", "wayland-client", "wayland-cursor", @@ -2263,9 +2304,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ "proc-macro2", "quote", @@ -2357,9 +2398,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.2" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ "autocfg", "bytes", @@ -2444,9 +2485,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" @@ -2502,11 +2543,11 @@ dependencies = [ [[package]] name = "uuid" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "serde", ] @@ -2752,7 +2793,7 @@ dependencies = [ "bitflags", "downcast-rs", "libc", - "nix", + "nix 0.24.2", "scoped-tls", "wayland-commons", "wayland-scanner", @@ -2765,7 +2806,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" dependencies = [ - "nix", + "nix 0.24.2", "once_cell", "smallvec", "wayland-sys", @@ -2777,7 +2818,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" dependencies = [ - "nix", + "nix 0.24.2", "wayland-client", "xcursor", ] @@ -3000,15 +3041,17 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.36.1" +version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53b97a83176b369b0eb2fd8158d4ae215357d02df9d40c1e1bf1879c5482c80" +checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", ] [[package]] @@ -3017,48 +3060,105 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winit" -version = "0.27.3" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22e94ba35ca3ff11820044bfa0dc48b95a3a15569c0068555566a12ef41c9e5" +checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" dependencies = [ "bitflags", "cocoa", @@ -3083,7 +3183,7 @@ dependencies = [ "wayland-client", "wayland-protocols", "web-sys", - "windows-sys", + "windows-sys 0.36.1", "x11-dl", ] diff --git a/Cargo.toml b/Cargo.toml index 9cc7cbcd3b..979c0ed4da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,7 +96,7 @@ android_system_properties = "0.1.1" # DX dependencies bit-set = "0.5" -gpu-allocator = { version = "0.20",default_features = false, features = ["d3d12", "windows", "public-winapi"] } +gpu-allocator = { version = "0.21",default_features = false, features = ["d3d12", "windows", "public-winapi"] } native = { package = "d3d12", version = "0.5.0" } range-alloc = "0.1" winapi = "0.3" From 6d3d10ff164b6b5c257a9b009e264f902f02ff88 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Wed, 7 Dec 2022 20:55:15 -0500 Subject: [PATCH 11/22] move gpu-allocator stuff into it's own file --- wgpu-hal/src/dx12/device.rs | 313 ++---------------- wgpu-hal/src/dx12/mod.rs | 47 +-- wgpu-hal/src/dx12/windows_rs_suballocation.rs | 303 +++++++++++++++++ 3 files changed, 333 insertions(+), 330 deletions(-) create mode 100644 wgpu-hal/src/dx12/windows_rs_suballocation.rs diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index c209386b66..7deaa07a77 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -3,30 +3,25 @@ use crate::{ FormatAspects, }; -use super::{conv, descriptor, view}; +use super::{ + conv, descriptor, view, + windows_rs_suballocation::{ + create_allocator_wrapper, free_buffer_allocation, free_texture_allocation, + }, +}; use parking_lot::Mutex; use std::{ffi, mem, num::NonZeroU32, ptr, slice, sync::Arc}; use winapi::{ shared::{dxgiformat, dxgitype, minwindef::BOOL, winerror}, - um::{d3d12, d3dcompiler, synchapi, winbase}, + um::{ + d3d12::{self, D3D12_RESOURCE_DESC}, + d3dcompiler, synchapi, winbase, + }, Interface, }; -#[cfg(not(feature = "windows_rs"))] -use winapi::um::d3d12::D3D12_RESOURCE_DESC; - -#[cfg(feature = "windows_rs")] -use gpu_allocator::{ - d3d12::{winapi_d3d12::D3D12_RESOURCE_DESC, AllocationCreateDesc, ToWinapi, ToWindows}, - MemoryLocation, -}; - // this has to match Naga's HLSL backend, and also needs to be null-terminated const NAGA_LOCATION_SEMANTIC: &[u8] = b"LOC\0"; -// TODO: find the exact value -// TODO: figure out if this is even needed? -#[allow(unused)] // TODO: Exists until windows-rs is standard, then it can probably be removed? -const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; impl super::Device { pub(super) fn new( @@ -35,18 +30,7 @@ impl super::Device { private_caps: super::PrivateCapabilities, library: &Arc, ) -> Result { - #[cfg(feature = "windows_rs")] - let mem_allocator = { - let device = raw.as_ptr(); - - match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc { - device: device.as_windows().clone(), - debug_settings: Default::default(), - }) { - Ok(allocator) => allocator, - Err(e) => panic!("Failed to create d3d12 allocator, error: {}", e), - } - }; + let mem_allocator = create_allocator_wrapper(&raw)?; let mut idle_fence = native::Fence::null(); let hr = unsafe { @@ -189,8 +173,7 @@ impl super::Device { #[cfg(feature = "renderdoc")] render_doc: Default::default(), null_rtv_handle, - #[cfg(feature = "windows_rs")] - mem_allocator: Mutex::new(mem_allocator), + mem_allocator, }) } @@ -338,14 +321,13 @@ impl super::Device { size, mip_level_count, sample_count, - #[cfg(feature = "windows_rs")] allocation: None, } } } impl crate::Device for super::Device { - unsafe fn exit(self, queue: super::Queue) { + unsafe fn exit(mut self, queue: super::Queue) { self.rtv_pool.lock().free_handle(self.null_rtv_handle); unsafe { self.rtv_pool.into_inner().destroy() }; unsafe { self.dsv_pool.into_inner().destroy() }; @@ -353,14 +335,16 @@ impl crate::Device for super::Device { unsafe { self.sampler_pool.into_inner().destroy() }; unsafe { self.shared.destroy() }; unsafe { self.idler.destroy() }; + drop(self.mem_allocator.take()); unsafe { queue.raw.destroy() }; } - #[cfg(feature = "windows_rs")] unsafe fn create_buffer( &self, desc: &crate::BufferDescriptor, ) -> Result { + use super::windows_rs_suballocation::my_buffer_hr; + let mut resource = native::Resource::null(); let mut size = desc.size; if desc.usage.contains(crate::BufferUses::UNIFORM) { @@ -370,7 +354,6 @@ impl crate::Device for super::Device { let raw_desc = D3D12_RESOURCE_DESC { Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, - // TODO: Alignment, see https://www.asawicki.info/news_1726_secrets_of_direct3d_12_resource_alignment Alignment: 0, Width: size, Height: 1, @@ -385,36 +368,7 @@ impl crate::Device for super::Device { Flags: conv::map_buffer_usage_to_resource_flags(desc.usage), }; - let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); - let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); - // TODO: These are probably wrong? - let location = match (is_cpu_read, is_cpu_write) { - (true, true) => MemoryLocation::CpuToGpu, - (true, false) => MemoryLocation::GpuToCpu, - (false, true) => MemoryLocation::CpuToGpu, - (false, false) => MemoryLocation::GpuOnly, - }; - - let mut allocator = self.mem_allocator.lock(); - let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( - allocator.device().as_winapi(), - &raw_desc, - "Example allocation", - location, - ); - let allocation = allocator.allocate(&allocation_desc)?; - - let hr = unsafe { - self.raw.CreatePlacedResource( - allocation.heap().as_winapi() as *mut _, - allocation.offset(), - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; + let (hr, allocation) = my_buffer_hr(self, desc, raw_desc, &mut resource)?; hr.into_device_result("Buffer creation")?; if let Some(label) = desc.label { @@ -425,104 +379,18 @@ impl crate::Device for super::Device { Ok(super::Buffer { resource, size, - allocation: Some(allocation), + allocation, }) } - #[cfg(not(feature = "windows_rs"))] - unsafe fn create_buffer( - &self, - desc: &crate::BufferDescriptor, - ) -> Result { - let mut resource = native::Resource::null(); - let mut size = desc.size; - if desc.usage.contains(crate::BufferUses::UNIFORM) { - let align_mask = d3d12::D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT as u64 - 1; - size = ((size - 1) | align_mask) + 1; - } - - let raw_desc = D3D12_RESOURCE_DESC { - Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, - Alignment: 0, - Width: size, - Height: 1, - DepthOrArraySize: 1, - MipLevels: 1, - Format: dxgiformat::DXGI_FORMAT_UNKNOWN, - SampleDesc: dxgitype::DXGI_SAMPLE_DESC { - Count: 1, - Quality: 0, - }, - Layout: d3d12::D3D12_TEXTURE_LAYOUT_ROW_MAJOR, - Flags: conv::map_buffer_usage_to_resource_flags(desc.usage), - }; - - let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); - let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); - - let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { - Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, - CPUPageProperty: if is_cpu_read { - d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK - } else if is_cpu_write { - d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE - } else { - d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE - }, - MemoryPoolPreference: match self.private_caps.memory_architecture { - super::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { - d3d12::D3D12_MEMORY_POOL_L1 - } - _ => d3d12::D3D12_MEMORY_POOL_L0, - }, - CreationNodeMask: 0, - VisibleNodeMask: 0, - }; - - let hr = unsafe { - self.raw.CreateCommittedResource( - &heap_properties, - if self.private_caps.heap_create_not_zeroed { - D3D12_HEAP_FLAG_CREATE_NOT_ZEROED - } else { - d3d12::D3D12_HEAP_FLAG_NONE - }, - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; - - hr.into_device_result("Buffer creation")?; - if let Some(label) = desc.label { - let cwstr = conv::map_label(label); - unsafe { resource.SetName(cwstr.as_ptr()) }; - } - - Ok(super::Buffer { resource, size }) - } - - #[cfg(feature = "windows_rs")] unsafe fn destroy_buffer(&self, mut buffer: super::Buffer) { - // TODO: Destroy or Release here? unsafe { buffer.resource.destroy() }; + // Only happens when it's using the windows_rs feature and there's an allocation if let Some(alloc) = buffer.allocation.take() { - match self.mem_allocator.lock().free(alloc) { - Ok(_) => (), - // TODO: Don't panic here - Err(e) => panic!("failed to destroy dx12 buffer, {}", e), - }; + free_buffer_allocation(alloc, self.mem_allocator.as_ref().unwrap()); } } - #[cfg(not(feature = "windows_rs"))] - unsafe fn destroy_buffer(&self, buffer: super::Buffer) { - unsafe { buffer.resource.destroy() }; - } - - #[cfg(feature = "windows_rs")] unsafe fn map_buffer( &self, buffer: &super::Buffer, @@ -541,31 +409,6 @@ impl crate::Device for super::Device { }) } - #[cfg(not(feature = "windows_rs"))] - unsafe fn map_buffer( - &self, - buffer: &super::Buffer, - range: crate::MemoryRange, - ) -> Result { - let mut ptr = ptr::null_mut(); - let hr = unsafe { (*buffer.resource).Map(0, ptr::null(), &mut ptr) }; - hr.into_device_result("Map buffer")?; - Ok(crate::BufferMapping { - ptr: ptr::NonNull::new(unsafe { ptr.offset(range.start as isize).cast::() }) - .unwrap(), - //TODO: double-check this. Documentation is a bit misleading - - // it implies that Map/Unmap is needed to invalidate/flush memory. - is_coherent: true, - }) - } - - #[cfg(feature = "windows_rs")] - unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> { - unsafe { (*buffer.resource).Unmap(0, ptr::null()) }; - Ok(()) - } - - #[cfg(not(feature = "windows_rs"))] unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> { unsafe { (*buffer.resource).Unmap(0, ptr::null()) }; Ok(()) @@ -574,87 +417,12 @@ impl crate::Device for super::Device { unsafe fn flush_mapped_ranges(&self, _buffer: &super::Buffer, _ranges: I) {} unsafe fn invalidate_mapped_ranges(&self, _buffer: &super::Buffer, _ranges: I) {} - #[cfg(feature = "windows_rs")] unsafe fn create_texture( &self, desc: &crate::TextureDescriptor, ) -> Result { - let mut resource = native::Resource::null(); - - let raw_desc = D3D12_RESOURCE_DESC { - Dimension: conv::map_texture_dimension(desc.dimension), - Alignment: 0, - Width: desc.size.width as u64, - Height: desc.size.height, - DepthOrArraySize: desc.size.depth_or_array_layers as u16, - MipLevels: desc.mip_level_count as u16, - Format: if crate::FormatAspects::from(desc.format).contains(crate::FormatAspects::COLOR) - || !desc.usage.intersects( - crate::TextureUses::RESOURCE - | crate::TextureUses::STORAGE_READ - | crate::TextureUses::STORAGE_READ_WRITE, - ) { - auxil::dxgi::conv::map_texture_format(desc.format) - } else { - // This branch is needed if it's a depth texture, and it's ever needed to be viewed as SRV or UAV, - // because then we'd create a non-depth format view of it. - // Note: we can skip this branch if - // `D3D12_FEATURE_D3D12_OPTIONS3::CastingFullyTypedFormatSupported` - auxil::dxgi::conv::map_texture_format_depth_typeless(desc.format) - }, - SampleDesc: dxgitype::DXGI_SAMPLE_DESC { - Count: desc.sample_count, - Quality: 0, - }, - Layout: d3d12::D3D12_TEXTURE_LAYOUT_UNKNOWN, - Flags: conv::map_texture_usage_to_resource_flags(desc.usage), - }; - - // TODO: What memory location should the texture be stored in? - let location = MemoryLocation::Unknown; - let mut allocator = self.mem_allocator.lock(); - let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( - allocator.device().as_winapi(), - &raw_desc, - "Example allocation", - location, - ); - let allocation = allocator.allocate(&allocation_desc)?; + use super::windows_rs_suballocation::my_texture_hr; - let hr = unsafe { - self.raw.CreatePlacedResource( - allocation.heap().as_winapi() as *mut _, - allocation.offset(), - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), // clear value - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; - - hr.into_device_result("Texture creation")?; - if let Some(label) = desc.label { - let cwstr = conv::map_label(label); - unsafe { resource.SetName(cwstr.as_ptr()) }; - } - - Ok(super::Texture { - resource, - format: desc.format, - dimension: desc.dimension, - size: desc.size, - mip_level_count: desc.mip_level_count, - sample_count: desc.sample_count, - allocation: Some(allocation), - }) - } - - #[cfg(not(feature = "windows_rs"))] - unsafe fn create_texture( - &self, - desc: &crate::TextureDescriptor, - ) -> Result { let mut resource = native::Resource::null(); let raw_desc = D3D12_RESOURCE_DESC { @@ -686,32 +454,7 @@ impl crate::Device for super::Device { Flags: conv::map_texture_usage_to_resource_flags(desc.usage), }; - let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { - Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, - CPUPageProperty: d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, - MemoryPoolPreference: match self.private_caps.memory_architecture { - super::MemoryArchitecture::NonUnified => d3d12::D3D12_MEMORY_POOL_L1, - super::MemoryArchitecture::Unified { .. } => d3d12::D3D12_MEMORY_POOL_L0, - }, - CreationNodeMask: 0, - VisibleNodeMask: 0, - }; - - let hr = unsafe { - self.raw.CreateCommittedResource( - &heap_properties, - if self.private_caps.heap_create_not_zeroed { - D3D12_HEAP_FLAG_CREATE_NOT_ZEROED - } else { - d3d12::D3D12_HEAP_FLAG_NONE - }, - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), // clear value - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; + let (hr, allocation) = my_texture_hr(self, raw_desc, &mut resource)?; hr.into_device_result("Texture creation")?; if let Some(label) = desc.label { @@ -726,25 +469,17 @@ impl crate::Device for super::Device { size: desc.size, mip_level_count: desc.mip_level_count, sample_count: desc.sample_count, + allocation, }) } - #[cfg(feature = "windows_rs")] unsafe fn destroy_texture(&self, mut texture: super::Texture) { unsafe { texture.resource.destroy() }; if let Some(alloc) = texture.allocation.take() { - match self.mem_allocator.lock().free(alloc) { - Ok(_) => (), - Err(e) => panic!("failed to destroy dx12 buffer, {}", e), - }; + free_texture_allocation(alloc, self.mem_allocator.as_ref().unwrap()); } } - #[cfg(not(feature = "windows_rs"))] - unsafe fn destroy_texture(&self, texture: super::Texture) { - unsafe { texture.resource.destroy() }; - } - unsafe fn create_texture_view( &self, texture: &super::Texture, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index ff91bf244e..7b6d6a530a 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -40,6 +40,7 @@ mod descriptor; mod device; mod instance; mod view; +mod windows_rs_suballocation; use crate::auxil::{self, dxgi::result::HResult as _}; @@ -52,6 +53,8 @@ use winapi::{ Interface as _, }; +use self::windows_rs_suballocation::{AllocationWrapper, GpuAllocatorWrapper}; + #[derive(Clone)] pub struct Api; @@ -238,8 +241,7 @@ pub struct Device { #[cfg(feature = "renderdoc")] render_doc: crate::auxil::renderdoc::RenderDoc, null_rtv_handle: descriptor::Handle, - #[cfg(feature = "windows_rs")] - mem_allocator: Mutex, + mem_allocator: Option>, } unsafe impl Send for Device {} @@ -375,8 +377,7 @@ unsafe impl Sync for CommandBuffer {} pub struct Buffer { resource: native::Resource, size: wgt::BufferAddress, - #[cfg(feature = "windows_rs")] - allocation: Option, + allocation: Option, } unsafe impl Send for Buffer {} @@ -403,8 +404,7 @@ pub struct Texture { size: wgt::Extent3d, mip_level_count: u32, sample_count: u32, - #[cfg(feature = "windows_rs")] - allocation: Option, + allocation: Option, } unsafe impl Send for Texture {} @@ -771,7 +771,6 @@ impl crate::Surface for Surface { size: sc.size, mip_level_count: 1, sample_count: 1, - #[cfg(feature = "windows_rs")] allocation: None, }; Ok(Some(crate::AcquiredSurfaceTexture { @@ -836,37 +835,3 @@ impl crate::Queue for Queue { (1_000_000_000.0 / frequency as f64) as f32 } } - -#[cfg(feature = "windows_rs")] -impl From for crate::DeviceError { - fn from(result: gpu_allocator::AllocationError) -> Self { - use log::error; - - match result { - gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, - gpu_allocator::AllocationError::FailedToMap(e) => { - error!("DX12 gpu-allocator: Failed to map: {}", e); - Self::Lost - } - gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => { - error!("DX12 gpu-allocator: No Compatible Memory Type Found"); - Self::Lost - } - gpu_allocator::AllocationError::InvalidAllocationCreateDesc => { - error!("DX12 gpu-allocator: Invalid Allocation Creation Description"); - Self::Lost - } - gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => { - error!( - "DX12 gpu-allocator: Invalid Allocator Creation Description: {}", - e - ); - Self::Lost - } - gpu_allocator::AllocationError::Internal(e) => { - error!("DX12 gpu-allocator: Internal Error: {}", e); - Self::Lost - } - } - } -} diff --git a/wgpu-hal/src/dx12/windows_rs_suballocation.rs b/wgpu-hal/src/dx12/windows_rs_suballocation.rs new file mode 100644 index 0000000000..984da099e0 --- /dev/null +++ b/wgpu-hal/src/dx12/windows_rs_suballocation.rs @@ -0,0 +1,303 @@ +use native::WeakPtr; +use parking_lot::Mutex; +use std::ptr; +use winapi::{ + um::{ + d3d12::{self, ID3D12Resource}, + winnt::HRESULT, + }, + Interface, +}; + +// This exists to work around https://github.com/gfx-rs/wgpu/issues/3207 +// Currently this will work the older, slower way if the windows_rs feature is disabled, +// and will suballocate buffers using gpu_allocator if the windows_rs feature is enabled. + +#[cfg(not(feature = "windows_rs"))] +use winapi::um::d3d12::D3D12_RESOURCE_DESC; + +#[cfg(feature = "windows_rs")] +use gpu_allocator::{ + d3d12::{winapi_d3d12::D3D12_RESOURCE_DESC, AllocationCreateDesc, ToWinapi, ToWindows}, + MemoryLocation, +}; + +// TODO: find the exact value +// TODO: figure out if this is even needed? +#[allow(unused)] // TODO: Exists until windows-rs is standard, then it can probably be removed? +pub(crate) const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; + +#[derive(Debug)] +pub(crate) struct GpuAllocatorWrapper { + #[cfg(feature = "windows_rs")] + pub(crate) allocator: gpu_allocator::d3d12::Allocator, + #[cfg(not(feature = "windows_rs"))] + #[allow(unused)] + pub(crate) allocator: (), +} + +#[derive(Debug)] +pub(crate) struct AllocationWrapper { + #[cfg(feature = "windows_rs")] + pub(crate) allocation: gpu_allocator::d3d12::Allocation, + #[cfg(not(feature = "windows_rs"))] + #[allow(unused)] + pub(crate) allocation: (), +} + +#[cfg(feature = "windows_rs")] +pub(crate) fn create_allocator_wrapper( + raw: &native::Device, +) -> Result>, crate::DeviceError> { + use log::error; + + let device = raw.as_ptr(); + + match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc { + device: device.as_windows().clone(), + debug_settings: Default::default(), + }) { + Ok(allocator) => return Ok(Some(Mutex::new(GpuAllocatorWrapper { allocator }))), + Err(e) => { + error!("Failed to create d3d12 allocator, error: {}", e); + Err(e)? + } + } +} + +#[cfg(not(feature = "windows_rs"))] +pub(crate) fn create_allocator_wrapper( + _raw: &native::Device, +) -> Result>, crate::DeviceError> { + Ok(None) +} + +#[cfg(feature = "windows_rs")] +pub(crate) fn my_buffer_hr( + device: &super::Device, + desc: &crate::BufferDescriptor, + raw_desc: D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, +) -> Result<(HRESULT, Option), crate::DeviceError> { + let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); + let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); + // TODO: These are probably wrong? + let location = match (is_cpu_read, is_cpu_write) { + (true, true) => MemoryLocation::CpuToGpu, + (true, false) => MemoryLocation::GpuToCpu, + (false, true) => MemoryLocation::CpuToGpu, + (false, false) => MemoryLocation::GpuOnly, + }; + + let mut allocator = device.mem_allocator.as_ref().unwrap().lock(); + let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( + allocator.allocator.device().as_winapi(), + &raw_desc, + "Example allocation", + location, + ); + let allocation = allocator.allocator.allocate(&allocation_desc)?; + + let hr = unsafe { + device.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; + + Ok((hr, Some(AllocationWrapper { allocation }))) +} + +#[cfg(not(feature = "windows_rs"))] +pub(crate) fn my_buffer_hr( + device: &super::Device, + desc: &crate::BufferDescriptor, + raw_desc: D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, +) -> Result<(HRESULT, Option), crate::DeviceError> { + let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); + let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); + + let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { + Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, + CPUPageProperty: if is_cpu_read { + d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK + } else if is_cpu_write { + d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE + } else { + d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE + }, + MemoryPoolPreference: match device.private_caps.memory_architecture { + super::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { + d3d12::D3D12_MEMORY_POOL_L1 + } + _ => d3d12::D3D12_MEMORY_POOL_L0, + }, + CreationNodeMask: 0, + VisibleNodeMask: 0, + }; + + let hr = unsafe { + device.raw.CreateCommittedResource( + &heap_properties, + if device.private_caps.heap_create_not_zeroed { + D3D12_HEAP_FLAG_CREATE_NOT_ZEROED + } else { + d3d12::D3D12_HEAP_FLAG_NONE + }, + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; + + Ok((hr, None)) +} + +#[cfg(feature = "windows_rs")] +pub(crate) fn my_texture_hr( + device: &super::Device, + raw_desc: D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, +) -> Result<(HRESULT, Option), crate::DeviceError> { + let location = MemoryLocation::GpuOnly; + let mut allocator = device.mem_allocator.as_ref().unwrap().lock(); + let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( + allocator.allocator.device().as_winapi(), + &raw_desc, + "Example allocation", + location, + ); + let allocation = allocator.allocator.allocate(&allocation_desc)?; + + let hr = unsafe { + device.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), // clear value + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; + + Ok((hr, Some(AllocationWrapper { allocation }))) +} + +#[cfg(not(feature = "windows_rs"))] +pub(crate) fn my_texture_hr( + device: &super::Device, + raw_desc: D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, +) -> Result<(HRESULT, Option), crate::DeviceError> { + let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { + Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, + CPUPageProperty: d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, + MemoryPoolPreference: match device.private_caps.memory_architecture { + super::MemoryArchitecture::NonUnified => d3d12::D3D12_MEMORY_POOL_L1, + super::MemoryArchitecture::Unified { .. } => d3d12::D3D12_MEMORY_POOL_L0, + }, + CreationNodeMask: 0, + VisibleNodeMask: 0, + }; + + let hr = unsafe { + device.raw.CreateCommittedResource( + &heap_properties, + if device.private_caps.heap_create_not_zeroed { + D3D12_HEAP_FLAG_CREATE_NOT_ZEROED + } else { + d3d12::D3D12_HEAP_FLAG_NONE + }, + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), // clear value + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; + + Ok((hr, None)) +} + +#[cfg(not(feature = "windows_rs"))] +pub(crate) fn free_buffer_allocation( + _allocation: AllocationWrapper, + _allocator: &Mutex, +) { + () +} + +#[cfg(feature = "windows_rs")] +pub(crate) fn free_buffer_allocation( + allocation: AllocationWrapper, + allocator: &Mutex, +) { + match allocator.lock().allocator.free(allocation.allocation) { + Ok(_) => (), + // TODO: Don't panic here + Err(e) => panic!("failed to destroy dx12 buffer, {}", e), + }; +} + +#[cfg(not(feature = "windows_rs"))] +pub(crate) fn free_texture_allocation( + _allocation: AllocationWrapper, + _allocator: &Mutex, +) { + () +} + +#[cfg(feature = "windows_rs")] +pub(crate) fn free_texture_allocation( + allocation: AllocationWrapper, + allocator: &Mutex, +) { + match allocator.lock().allocator.free(allocation.allocation) { + Ok(_) => (), + // TODO: Don't panic here + Err(e) => panic!("failed to destroy dx12 texture, {}", e), + }; +} + +#[cfg(feature = "windows_rs")] +impl From for crate::DeviceError { + fn from(result: gpu_allocator::AllocationError) -> Self { + use log::error; + + match result { + gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, + gpu_allocator::AllocationError::FailedToMap(e) => { + error!("DX12 gpu-allocator: Failed to map: {}", e); + Self::Lost + } + gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => { + error!("DX12 gpu-allocator: No Compatible Memory Type Found"); + Self::Lost + } + gpu_allocator::AllocationError::InvalidAllocationCreateDesc => { + error!("DX12 gpu-allocator: Invalid Allocation Creation Description"); + Self::Lost + } + gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => { + error!( + "DX12 gpu-allocator: Invalid Allocator Creation Description: {}", + e + ); + Self::Lost + } + gpu_allocator::AllocationError::Internal(e) => { + error!("DX12 gpu-allocator: Internal Error: {}", e); + Self::Lost + } + } + } +} From b574495e398a5f70b9f05d21930e35dae4292cfd Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Wed, 7 Dec 2022 21:07:06 -0500 Subject: [PATCH 12/22] clippy --- wgpu-hal/src/dx12/device.rs | 3 ++- wgpu-hal/src/dx12/windows_rs_suballocation.rs | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 7deaa07a77..8dbd27a4af 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -327,7 +327,7 @@ impl super::Device { } impl crate::Device for super::Device { - unsafe fn exit(mut self, queue: super::Queue) { + unsafe fn exit(#[allow(unused_mut)] mut self, queue: super::Queue) { self.rtv_pool.lock().free_handle(self.null_rtv_handle); unsafe { self.rtv_pool.into_inner().destroy() }; unsafe { self.dsv_pool.into_inner().destroy() }; @@ -335,6 +335,7 @@ impl crate::Device for super::Device { unsafe { self.sampler_pool.into_inner().destroy() }; unsafe { self.shared.destroy() }; unsafe { self.idler.destroy() }; + #[cfg(feature = "windows_rs")] drop(self.mem_allocator.take()); unsafe { queue.raw.destroy() }; } diff --git a/wgpu-hal/src/dx12/windows_rs_suballocation.rs b/wgpu-hal/src/dx12/windows_rs_suballocation.rs index 984da099e0..bf55fde9c8 100644 --- a/wgpu-hal/src/dx12/windows_rs_suballocation.rs +++ b/wgpu-hal/src/dx12/windows_rs_suballocation.rs @@ -57,7 +57,7 @@ pub(crate) fn create_allocator_wrapper( device: device.as_windows().clone(), debug_settings: Default::default(), }) { - Ok(allocator) => return Ok(Some(Mutex::new(GpuAllocatorWrapper { allocator }))), + Ok(allocator) => Ok(Some(Mutex::new(GpuAllocatorWrapper { allocator }))), Err(e) => { error!("Failed to create d3d12 allocator, error: {}", e); Err(e)? @@ -233,7 +233,7 @@ pub(crate) fn free_buffer_allocation( _allocation: AllocationWrapper, _allocator: &Mutex, ) { - () + // No-op when not using gpu-allocator } #[cfg(feature = "windows_rs")] @@ -253,7 +253,7 @@ pub(crate) fn free_texture_allocation( _allocation: AllocationWrapper, _allocator: &Mutex, ) { - () + // No-op when not using gpu-allocator } #[cfg(feature = "windows_rs")] From edb3b49c2c041a293861b9ba4a0f26703af5a680 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Wed, 7 Dec 2022 21:33:28 -0500 Subject: [PATCH 13/22] cargo update so it builds --- Cargo.lock | 103 +++++++++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43f302b69f..93aae9868f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -75,9 +75,9 @@ dependencies = [ [[package]] name = "ash" -version = "0.37.0+1.3.209" +version = "0.37.1+1.3.235" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006ca68e0f2b03f22d6fa9f2860f85aed430d257fec20f8879b2145e7c7ae1a6" +checksum = "911015c962d56e2e4052f40182ca5462ba60a3d2ff04e827c365a0ab3d65726d" dependencies = [ "libloading", ] @@ -114,9 +114,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" dependencies = [ "proc-macro2", "quote", @@ -247,12 +247,12 @@ checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "calloop" -version = "0.10.3" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bcf530afb40e45e14440701e5e996d7fd139e84a912a4d83a8d6a0fb3e58663" +checksum = "595eb0438b3c6d262395fe30e6de9a61beb57ea56290b00a07f227fe6e20cbf2" dependencies = [ "log", - "nix 0.25.0", + "nix", "slotmap", "thiserror", "vec_map", @@ -439,9 +439,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", ] @@ -1310,9 +1310,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libloading" @@ -1505,18 +1505,18 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.4.0+25.0.8775105" +version = "0.4.1+23.1.7779620" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f74ddd54b7da8d38d399faf43472ac9759f1a028a45c83154bff603e0f56385a" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" dependencies = [ "jni-sys", ] [[package]] name = "nix" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ "bitflags", "cfg-if", @@ -1524,19 +1524,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "nix" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" -dependencies = [ - "autocfg", - "bitflags", - "cfg-if", - "libc", - "memoffset", -] - [[package]] name = "noise" version = "0.7.0" @@ -1642,9 +1629,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "osmesa-sys" @@ -1685,7 +1672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.4", + "parking_lot_core 0.9.5", ] [[package]] @@ -1704,9 +1691,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" dependencies = [ "cfg-if", "libc", @@ -1953,9 +1940,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", @@ -2099,9 +2086,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] @@ -2117,9 +2104,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -2128,9 +2115,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.88" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "indexmap", "itoa", @@ -2248,7 +2235,7 @@ dependencies = [ "lazy_static", "log", "memmap2", - "nix 0.24.2", + "nix", "pkg-config", "wayland-client", "wayland-cursor", @@ -2271,7 +2258,7 @@ version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c46fdc1838ff49cf692226f5c2b0f5b7538f556863d0eca602984714667ac6e7" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "if_chain", "lazy_static", "regex", @@ -2305,9 +2292,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", @@ -2399,9 +2386,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" dependencies = [ "autocfg", "bytes", @@ -2420,9 +2407,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", @@ -2545,9 +2532,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.2.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" dependencies = [ "getrandom 0.2.8", "serde", @@ -2794,7 +2781,7 @@ dependencies = [ "bitflags", "downcast-rs", "libc", - "nix 0.24.2", + "nix", "scoped-tls", "wayland-commons", "wayland-scanner", @@ -2807,7 +2794,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" dependencies = [ - "nix 0.24.2", + "nix", "once_cell", "smallvec", "wayland-sys", @@ -2819,7 +2806,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" dependencies = [ - "nix 0.24.2", + "nix", "wayland-client", "xcursor", ] @@ -3261,9 +3248,9 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.20.0" +version = "2.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6" +checksum = "b1536d6965a5d4e573c7ef73a2c15ebcd0b2de3347bdf526c34c297c00ac40f0" dependencies = [ "lazy_static", "libc", From 2dace15c640ba5ab529de44bf2dd5049a094c0e2 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 8 Dec 2022 21:27:53 -0500 Subject: [PATCH 14/22] cleanup --- wgpu-hal/src/dx12/device.rs | 44 ++++++++--------- wgpu-hal/src/dx12/mod.rs | 10 ++-- ...s_rs_suballocation.rs => suballocation.rs} | 48 ++++++++++--------- 3 files changed, 49 insertions(+), 53 deletions(-) rename wgpu-hal/src/dx12/{windows_rs_suballocation.rs => suballocation.rs} (89%) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 8dbd27a4af..c2da1df388 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -3,20 +3,12 @@ use crate::{ FormatAspects, }; -use super::{ - conv, descriptor, view, - windows_rs_suballocation::{ - create_allocator_wrapper, free_buffer_allocation, free_texture_allocation, - }, -}; +use super::{conv, descriptor, view}; use parking_lot::Mutex; use std::{ffi, mem, num::NonZeroU32, ptr, slice, sync::Arc}; use winapi::{ shared::{dxgiformat, dxgitype, minwindef::BOOL, winerror}, - um::{ - d3d12::{self, D3D12_RESOURCE_DESC}, - d3dcompiler, synchapi, winbase, - }, + um::{d3d12, d3dcompiler, synchapi, winbase}, Interface, }; @@ -30,7 +22,7 @@ impl super::Device { private_caps: super::PrivateCapabilities, library: &Arc, ) -> Result { - let mem_allocator = create_allocator_wrapper(&raw)?; + let mem_allocator = super::suballocation::create_allocator_wrapper(&raw)?; let mut idle_fence = native::Fence::null(); let hr = unsafe { @@ -46,7 +38,7 @@ impl super::Device { let mut zero_buffer = native::Resource::null(); unsafe { - let raw_desc = D3D12_RESOURCE_DESC { + let raw_desc = d3d12::D3D12_RESOURCE_DESC { Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, Alignment: 0, Width: super::ZERO_BUFFER_SIZE, @@ -327,7 +319,7 @@ impl super::Device { } impl crate::Device for super::Device { - unsafe fn exit(#[allow(unused_mut)] mut self, queue: super::Queue) { + unsafe fn exit(mut self, queue: super::Queue) { self.rtv_pool.lock().free_handle(self.null_rtv_handle); unsafe { self.rtv_pool.into_inner().destroy() }; unsafe { self.dsv_pool.into_inner().destroy() }; @@ -335,8 +327,7 @@ impl crate::Device for super::Device { unsafe { self.sampler_pool.into_inner().destroy() }; unsafe { self.shared.destroy() }; unsafe { self.idler.destroy() }; - #[cfg(feature = "windows_rs")] - drop(self.mem_allocator.take()); + self.mem_allocator = None; unsafe { queue.raw.destroy() }; } @@ -344,8 +335,6 @@ impl crate::Device for super::Device { &self, desc: &crate::BufferDescriptor, ) -> Result { - use super::windows_rs_suballocation::my_buffer_hr; - let mut resource = native::Resource::null(); let mut size = desc.size; if desc.usage.contains(crate::BufferUses::UNIFORM) { @@ -353,7 +342,7 @@ impl crate::Device for super::Device { size = ((size - 1) | align_mask) + 1; } - let raw_desc = D3D12_RESOURCE_DESC { + let raw_desc = d3d12::D3D12_RESOURCE_DESC { Dimension: d3d12::D3D12_RESOURCE_DIMENSION_BUFFER, Alignment: 0, Width: size, @@ -369,7 +358,8 @@ impl crate::Device for super::Device { Flags: conv::map_buffer_usage_to_resource_flags(desc.usage), }; - let (hr, allocation) = my_buffer_hr(self, desc, raw_desc, &mut resource)?; + let (hr, allocation) = + super::suballocation::create_buffer_resource(self, desc, raw_desc, &mut resource)?; hr.into_device_result("Buffer creation")?; if let Some(label) = desc.label { @@ -388,7 +378,10 @@ impl crate::Device for super::Device { unsafe { buffer.resource.destroy() }; // Only happens when it's using the windows_rs feature and there's an allocation if let Some(alloc) = buffer.allocation.take() { - free_buffer_allocation(alloc, self.mem_allocator.as_ref().unwrap()); + super::suballocation::free_buffer_allocation( + alloc, + self.mem_allocator.as_ref().unwrap(), + ); } } @@ -422,11 +415,11 @@ impl crate::Device for super::Device { &self, desc: &crate::TextureDescriptor, ) -> Result { - use super::windows_rs_suballocation::my_texture_hr; + use super::suballocation::create_texture_resource; let mut resource = native::Resource::null(); - let raw_desc = D3D12_RESOURCE_DESC { + let raw_desc = d3d12::D3D12_RESOURCE_DESC { Dimension: conv::map_texture_dimension(desc.dimension), Alignment: 0, Width: desc.size.width as u64, @@ -455,7 +448,7 @@ impl crate::Device for super::Device { Flags: conv::map_texture_usage_to_resource_flags(desc.usage), }; - let (hr, allocation) = my_texture_hr(self, raw_desc, &mut resource)?; + let (hr, allocation) = create_texture_resource(self, desc, raw_desc, &mut resource)?; hr.into_device_result("Texture creation")?; if let Some(label) = desc.label { @@ -477,7 +470,10 @@ impl crate::Device for super::Device { unsafe fn destroy_texture(&self, mut texture: super::Texture) { unsafe { texture.resource.destroy() }; if let Some(alloc) = texture.allocation.take() { - free_texture_allocation(alloc, self.mem_allocator.as_ref().unwrap()); + super::suballocation::free_texture_allocation( + alloc, + self.mem_allocator.as_ref().unwrap(), + ); } } diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 7b6d6a530a..1e34188ed4 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -39,8 +39,8 @@ mod conv; mod descriptor; mod device; mod instance; +mod suballocation; mod view; -mod windows_rs_suballocation; use crate::auxil::{self, dxgi::result::HResult as _}; @@ -53,8 +53,6 @@ use winapi::{ Interface as _, }; -use self::windows_rs_suballocation::{AllocationWrapper, GpuAllocatorWrapper}; - #[derive(Clone)] pub struct Api; @@ -241,7 +239,7 @@ pub struct Device { #[cfg(feature = "renderdoc")] render_doc: crate::auxil::renderdoc::RenderDoc, null_rtv_handle: descriptor::Handle, - mem_allocator: Option>, + mem_allocator: Option>, } unsafe impl Send for Device {} @@ -377,7 +375,7 @@ unsafe impl Sync for CommandBuffer {} pub struct Buffer { resource: native::Resource, size: wgt::BufferAddress, - allocation: Option, + allocation: Option, } unsafe impl Send for Buffer {} @@ -404,7 +402,7 @@ pub struct Texture { size: wgt::Extent3d, mip_level_count: u32, sample_count: u32, - allocation: Option, + allocation: Option, } unsafe impl Send for Texture {} diff --git a/wgpu-hal/src/dx12/windows_rs_suballocation.rs b/wgpu-hal/src/dx12/suballocation.rs similarity index 89% rename from wgpu-hal/src/dx12/windows_rs_suballocation.rs rename to wgpu-hal/src/dx12/suballocation.rs index bf55fde9c8..2eb9dce628 100644 --- a/wgpu-hal/src/dx12/windows_rs_suballocation.rs +++ b/wgpu-hal/src/dx12/suballocation.rs @@ -13,12 +13,9 @@ use winapi::{ // Currently this will work the older, slower way if the windows_rs feature is disabled, // and will suballocate buffers using gpu_allocator if the windows_rs feature is enabled. -#[cfg(not(feature = "windows_rs"))] -use winapi::um::d3d12::D3D12_RESOURCE_DESC; - #[cfg(feature = "windows_rs")] use gpu_allocator::{ - d3d12::{winapi_d3d12::D3D12_RESOURCE_DESC, AllocationCreateDesc, ToWinapi, ToWindows}, + d3d12::{AllocationCreateDesc, ToWinapi, ToWindows}, MemoryLocation, }; @@ -73,10 +70,10 @@ pub(crate) fn create_allocator_wrapper( } #[cfg(feature = "windows_rs")] -pub(crate) fn my_buffer_hr( +pub(crate) fn create_buffer_resource( device: &super::Device, desc: &crate::BufferDescriptor, - raw_desc: D3D12_RESOURCE_DESC, + raw_desc: d3d12::D3D12_RESOURCE_DESC, resource: &mut WeakPtr, ) -> Result<(HRESULT, Option), crate::DeviceError> { let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); @@ -89,11 +86,13 @@ pub(crate) fn my_buffer_hr( (false, false) => MemoryLocation::GpuOnly, }; + let name = desc.label.unwrap_or("Unlabeled buffer"); + let mut allocator = device.mem_allocator.as_ref().unwrap().lock(); let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( allocator.allocator.device().as_winapi(), &raw_desc, - "Example allocation", + name, location, ); let allocation = allocator.allocator.allocate(&allocation_desc)?; @@ -114,10 +113,10 @@ pub(crate) fn my_buffer_hr( } #[cfg(not(feature = "windows_rs"))] -pub(crate) fn my_buffer_hr( +pub(crate) fn create_buffer_resource( device: &super::Device, desc: &crate::BufferDescriptor, - raw_desc: D3D12_RESOURCE_DESC, + raw_desc: d3d12::D3D12_RESOURCE_DESC, resource: &mut WeakPtr, ) -> Result<(HRESULT, Option), crate::DeviceError> { let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); @@ -162,17 +161,21 @@ pub(crate) fn my_buffer_hr( } #[cfg(feature = "windows_rs")] -pub(crate) fn my_texture_hr( +pub(crate) fn create_texture_resource( device: &super::Device, - raw_desc: D3D12_RESOURCE_DESC, + desc: &crate::TextureDescriptor, + raw_desc: d3d12::D3D12_RESOURCE_DESC, resource: &mut WeakPtr, ) -> Result<(HRESULT, Option), crate::DeviceError> { let location = MemoryLocation::GpuOnly; + + let name = desc.label.unwrap_or("Unlabeled texture"); + let mut allocator = device.mem_allocator.as_ref().unwrap().lock(); let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( allocator.allocator.device().as_winapi(), &raw_desc, - "Example allocation", + name, location, ); let allocation = allocator.allocator.allocate(&allocation_desc)?; @@ -193,9 +196,10 @@ pub(crate) fn my_texture_hr( } #[cfg(not(feature = "windows_rs"))] -pub(crate) fn my_texture_hr( +pub(crate) fn create_texture_resource( device: &super::Device, - raw_desc: D3D12_RESOURCE_DESC, + _desc: &crate::TextureDescriptor, + raw_desc: d3d12::D3D12_RESOURCE_DESC, resource: &mut WeakPtr, ) -> Result<(HRESULT, Option), crate::DeviceError> { let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { @@ -244,7 +248,7 @@ pub(crate) fn free_buffer_allocation( match allocator.lock().allocator.free(allocation.allocation) { Ok(_) => (), // TODO: Don't panic here - Err(e) => panic!("failed to destroy dx12 buffer, {}", e), + Err(e) => panic!("Failed to destroy dx12 buffer, {}", e), }; } @@ -264,38 +268,36 @@ pub(crate) fn free_texture_allocation( match allocator.lock().allocator.free(allocation.allocation) { Ok(_) => (), // TODO: Don't panic here - Err(e) => panic!("failed to destroy dx12 texture, {}", e), + Err(e) => panic!("Failed to destroy dx12 texture, {}", e), }; } #[cfg(feature = "windows_rs")] impl From for crate::DeviceError { fn from(result: gpu_allocator::AllocationError) -> Self { - use log::error; - match result { gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, gpu_allocator::AllocationError::FailedToMap(e) => { - error!("DX12 gpu-allocator: Failed to map: {}", e); + log::error!("DX12 gpu-allocator: Failed to map: {}", e); Self::Lost } gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => { - error!("DX12 gpu-allocator: No Compatible Memory Type Found"); + log::error!("DX12 gpu-allocator: No Compatible Memory Type Found"); Self::Lost } gpu_allocator::AllocationError::InvalidAllocationCreateDesc => { - error!("DX12 gpu-allocator: Invalid Allocation Creation Description"); + log::error!("DX12 gpu-allocator: Invalid Allocation Creation Description"); Self::Lost } gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => { - error!( + log::error!( "DX12 gpu-allocator: Invalid Allocator Creation Description: {}", e ); Self::Lost } gpu_allocator::AllocationError::Internal(e) => { - error!("DX12 gpu-allocator: Internal Error: {}", e); + log::error!("DX12 gpu-allocator: Internal Error: {}", e); Self::Lost } } From 757b841c2a5e2e1e5b3e30af74852c2dfe642cf8 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 01:45:18 -0500 Subject: [PATCH 15/22] unwrap_unchecked when getting the allocator --- wgpu-hal/src/dx12/device.rs | 6 ++++-- wgpu-hal/src/dx12/suballocation.rs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index c2da1df388..b9a0c7e566 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -380,7 +380,8 @@ impl crate::Device for super::Device { if let Some(alloc) = buffer.allocation.take() { super::suballocation::free_buffer_allocation( alloc, - self.mem_allocator.as_ref().unwrap(), + // SAFETY: for allocations to exist, the allocator must exist + unsafe { self.mem_allocator.as_ref().unwrap_unchecked() }, ); } } @@ -472,7 +473,8 @@ impl crate::Device for super::Device { if let Some(alloc) = texture.allocation.take() { super::suballocation::free_texture_allocation( alloc, - self.mem_allocator.as_ref().unwrap(), + // SAFETY: for allocations to exist, the allocator must exist + unsafe { self.mem_allocator.as_ref().unwrap_unchecked() }, ); } } diff --git a/wgpu-hal/src/dx12/suballocation.rs b/wgpu-hal/src/dx12/suballocation.rs index 2eb9dce628..175e193b77 100644 --- a/wgpu-hal/src/dx12/suballocation.rs +++ b/wgpu-hal/src/dx12/suballocation.rs @@ -88,7 +88,8 @@ pub(crate) fn create_buffer_resource( let name = desc.label.unwrap_or("Unlabeled buffer"); - let mut allocator = device.mem_allocator.as_ref().unwrap().lock(); + // SAFETY: allocator exists when the windows_rs feature is enabled + let mut allocator = unsafe { device.mem_allocator.as_ref().unwrap_unchecked().lock() }; let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( allocator.allocator.device().as_winapi(), &raw_desc, @@ -171,7 +172,8 @@ pub(crate) fn create_texture_resource( let name = desc.label.unwrap_or("Unlabeled texture"); - let mut allocator = device.mem_allocator.as_ref().unwrap().lock(); + // SAFETY: allocator exists when the windows_rs feature is enabled + let mut allocator = unsafe { device.mem_allocator.as_ref().unwrap_unchecked().lock() }; let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( allocator.allocator.device().as_winapi(), &raw_desc, From 079a343c7a448d6570a23631d7dba9523b4aed52 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 02:53:59 -0500 Subject: [PATCH 16/22] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eeb30f96e6..2993d0c06b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,10 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non `Instance::create_surface()` now returns `Result` instead of `Surface`. This allows an error to be returned instead of panicking if the given window is a HTML canvas and obtaining a WebGPU or WebGL 2 context fails. (No other platforms currently report any errors through this path.) By @kpreid in [#3052](https://github.com/gfx-rs/wgpu/pull/3052/) +#### Suballocate DX12 buffers and textures + +`wgpu`'s DX12 backend can now suballocate buffers and textures when the `windows_rs` feature is enabled, which can give a significant increase in performance (in testing I've seen a 10000%+ improvement in a simple scene with 200 `write_buffer` calls per frame, and a 40%+ improvement in [Bistro using Bevy](https://github.com/vleue/bevy_bistro_playground)). Previously `wgpu-hal`'s DX12 backend created a new heap on the GPU every time you called write_buffer (by calling `CreateCommittedResource`), whereas now with the `windows_rs` feature enabled it uses [`gpu_allocator`](https://crates.io/crates/gpu-allocator) to manage GPU memory (and calls `CreatePlacedResource` with a suballocated heap). By @Elabajaba in [#3163](https://github.com/gfx-rs/wgpu/pull/3163) + ### Changes #### General From 1afd89f6afa9c4aba2ae2740d02bc6cc8077157d Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 03:01:52 -0500 Subject: [PATCH 17/22] can't use workspace inheritance :( --- Cargo.toml | 2 +- wgpu-hal/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2e828fd936..7b693ae1a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,7 +95,7 @@ android_system_properties = "0.1.1" # DX dependencies bit-set = "0.5" -gpu-allocator = { version = "0.21",default_features = false, features = ["d3d12", "windows", "public-winapi"] } +gpu-allocator = { version = "0.21", default_features = false, features = ["d3d12", "windows", "public-winapi"] } native = { package = "d3d12", version = "0.5.0" } range-alloc = "0.1" winapi = "0.3" diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index db0e981240..95aea0e80b 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -74,7 +74,7 @@ glow = { git = "https://github.com/grovesNL/glow", rev = "c8a011fcd57a5c68cc917e # backend: Dx12 bit-set = { version = "0.5", optional = true } range-alloc = { version = "0.1", optional = true } -gpu-allocator = { workspace = true, optional = true } +gpu-allocator = { version = "0.21", default_features = false, features = ["d3d12", "windows", "public-winapi"], optional = true } [dependencies.wgt] package = "wgpu-types" From 35c583013cf04b2a5a8a9fa1e9d275100f871bb4 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 20:57:32 -0500 Subject: [PATCH 18/22] Implement strict_assert for unwrap_unchecked --- wgpu-types/src/assertions.rs | 20 ++++++++++++++++++++ wgpu-types/src/lib.rs | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/wgpu-types/src/assertions.rs b/wgpu-types/src/assertions.rs index 87b4de33ef..80a54c211e 100644 --- a/wgpu-types/src/assertions.rs +++ b/wgpu-types/src/assertions.rs @@ -64,3 +64,23 @@ macro_rules! strict_assert_ne { debug_assert_ne!( $( $arg )* ) }; } + +/// Used to implement strict_assert for unwrap_unchecked +pub trait StrictAssertUnwrapExt { + /// Implementation of strict_assert for unwrap_unchecked + fn strict_unwrap_unchecked(self) -> T; +} + +impl StrictAssertUnwrapExt for Option { + fn strict_unwrap_unchecked(self) -> T { + strict_assert!(self.is_some(), "Called strict_unwrap_unchecked on None"); + unsafe { self.unwrap_unchecked() } + } +} + +impl StrictAssertUnwrapExt for Result { + fn strict_unwrap_unchecked(self) -> T { + strict_assert!(self.is_ok(), "Called strict_unwrap_unchecked on Err"); + unsafe { self.unwrap_unchecked() } + } +} \ No newline at end of file diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 4d648f45e9..a4fc019585 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; use std::{num::NonZeroU32, ops::Range}; -mod assertions; +pub mod assertions; // Use this macro instead of the one provided by the bitflags_serde_shim crate // because the latter produces an error when deserializing bits that are not From 148185425724d16d2f4503f5c31112095694a8aa Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 21:02:48 -0500 Subject: [PATCH 19/22] split suballocation into 2 inline modules for readability --- wgpu-hal/src/dx12/suballocation.rs | 555 +++++++++++++++-------------- 1 file changed, 284 insertions(+), 271 deletions(-) diff --git a/wgpu-hal/src/dx12/suballocation.rs b/wgpu-hal/src/dx12/suballocation.rs index 175e193b77..6085d66566 100644 --- a/wgpu-hal/src/dx12/suballocation.rs +++ b/wgpu-hal/src/dx12/suballocation.rs @@ -1,307 +1,320 @@ -use native::WeakPtr; -use parking_lot::Mutex; -use std::ptr; -use winapi::{ - um::{ - d3d12::{self, ID3D12Resource}, - winnt::HRESULT, - }, - Interface, +pub(crate) use allocation::{ + create_allocator_wrapper, create_buffer_resource, create_texture_resource, + free_buffer_allocation, free_texture_allocation, AllocationWrapper, GpuAllocatorWrapper, }; -// This exists to work around https://github.com/gfx-rs/wgpu/issues/3207 -// Currently this will work the older, slower way if the windows_rs feature is disabled, -// and will suballocate buffers using gpu_allocator if the windows_rs feature is enabled. - #[cfg(feature = "windows_rs")] -use gpu_allocator::{ - d3d12::{AllocationCreateDesc, ToWinapi, ToWindows}, - MemoryLocation, -}; +mod allocation { + use native::WeakPtr; + use parking_lot::Mutex; + use std::ptr; + use wgt::assertions::StrictAssertUnwrapExt; + use winapi::{ + um::{ + d3d12::{self, ID3D12Resource}, + winnt::HRESULT, + }, + Interface, + }; -// TODO: find the exact value -// TODO: figure out if this is even needed? -#[allow(unused)] // TODO: Exists until windows-rs is standard, then it can probably be removed? -pub(crate) const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; + use gpu_allocator::{ + d3d12::{AllocationCreateDesc, ToWinapi, ToWindows}, + MemoryLocation, + }; -#[derive(Debug)] -pub(crate) struct GpuAllocatorWrapper { - #[cfg(feature = "windows_rs")] - pub(crate) allocator: gpu_allocator::d3d12::Allocator, - #[cfg(not(feature = "windows_rs"))] - #[allow(unused)] - pub(crate) allocator: (), -} + #[derive(Debug)] + pub(crate) struct GpuAllocatorWrapper { + pub(crate) allocator: gpu_allocator::d3d12::Allocator, + } -#[derive(Debug)] -pub(crate) struct AllocationWrapper { - #[cfg(feature = "windows_rs")] - pub(crate) allocation: gpu_allocator::d3d12::Allocation, - #[cfg(not(feature = "windows_rs"))] - #[allow(unused)] - pub(crate) allocation: (), -} + #[derive(Debug)] + pub(crate) struct AllocationWrapper { + pub(crate) allocation: gpu_allocator::d3d12::Allocation, + } -#[cfg(feature = "windows_rs")] -pub(crate) fn create_allocator_wrapper( - raw: &native::Device, -) -> Result>, crate::DeviceError> { - use log::error; - - let device = raw.as_ptr(); - - match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc { - device: device.as_windows().clone(), - debug_settings: Default::default(), - }) { - Ok(allocator) => Ok(Some(Mutex::new(GpuAllocatorWrapper { allocator }))), - Err(e) => { - error!("Failed to create d3d12 allocator, error: {}", e); - Err(e)? + pub(crate) fn create_allocator_wrapper( + raw: &native::Device, + ) -> Result>, crate::DeviceError> { + let device = raw.as_ptr(); + + match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc { + device: device.as_windows().clone(), + debug_settings: Default::default(), + }) { + Ok(allocator) => Ok(Some(Mutex::new(GpuAllocatorWrapper { allocator }))), + Err(e) => { + log::error!("Failed to create d3d12 allocator, error: {}", e); + Err(e)? + } } } -} -#[cfg(not(feature = "windows_rs"))] -pub(crate) fn create_allocator_wrapper( - _raw: &native::Device, -) -> Result>, crate::DeviceError> { - Ok(None) -} + pub(crate) fn create_buffer_resource( + device: &crate::dx12::Device, + desc: &crate::BufferDescriptor, + raw_desc: d3d12::D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, + ) -> Result<(HRESULT, Option), crate::DeviceError> { + let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); + let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); + let location = match (is_cpu_read, is_cpu_write) { + (true, true) => MemoryLocation::CpuToGpu, + (true, false) => MemoryLocation::GpuToCpu, + (false, true) => MemoryLocation::CpuToGpu, + (false, false) => MemoryLocation::GpuOnly, + }; -#[cfg(feature = "windows_rs")] -pub(crate) fn create_buffer_resource( - device: &super::Device, - desc: &crate::BufferDescriptor, - raw_desc: d3d12::D3D12_RESOURCE_DESC, - resource: &mut WeakPtr, -) -> Result<(HRESULT, Option), crate::DeviceError> { - let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); - let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); - // TODO: These are probably wrong? - let location = match (is_cpu_read, is_cpu_write) { - (true, true) => MemoryLocation::CpuToGpu, - (true, false) => MemoryLocation::GpuToCpu, - (false, true) => MemoryLocation::CpuToGpu, - (false, false) => MemoryLocation::GpuOnly, - }; + let name = desc.label.unwrap_or("Unlabeled buffer"); + + // SAFETY: allocator exists when the windows_rs feature is enabled + let mut allocator = device + .mem_allocator + .as_ref() + .strict_unwrap_unchecked() + .lock(); - let name = desc.label.unwrap_or("Unlabeled buffer"); - - // SAFETY: allocator exists when the windows_rs feature is enabled - let mut allocator = unsafe { device.mem_allocator.as_ref().unwrap_unchecked().lock() }; - let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( - allocator.allocator.device().as_winapi(), - &raw_desc, - name, - location, - ); - let allocation = allocator.allocator.allocate(&allocation_desc)?; - - let hr = unsafe { - device.raw.CreatePlacedResource( - allocation.heap().as_winapi() as *mut _, - allocation.offset(), + // let mut allocator = unsafe { device.mem_allocator.as_ref().unwrap_unchecked().lock() }; + let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( + allocator.allocator.device().as_winapi(), &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; + name, + location, + ); + let allocation = allocator.allocator.allocate(&allocation_desc)?; - Ok((hr, Some(AllocationWrapper { allocation }))) -} + let hr = unsafe { + device.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; -#[cfg(not(feature = "windows_rs"))] -pub(crate) fn create_buffer_resource( - device: &super::Device, - desc: &crate::BufferDescriptor, - raw_desc: d3d12::D3D12_RESOURCE_DESC, - resource: &mut WeakPtr, -) -> Result<(HRESULT, Option), crate::DeviceError> { - let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); - let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); - - let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { - Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, - CPUPageProperty: if is_cpu_read { - d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK - } else if is_cpu_write { - d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE - } else { - d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE - }, - MemoryPoolPreference: match device.private_caps.memory_architecture { - super::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { - d3d12::D3D12_MEMORY_POOL_L1 - } - _ => d3d12::D3D12_MEMORY_POOL_L0, - }, - CreationNodeMask: 0, - VisibleNodeMask: 0, - }; + Ok((hr, Some(AllocationWrapper { allocation }))) + } - let hr = unsafe { - device.raw.CreateCommittedResource( - &heap_properties, - if device.private_caps.heap_create_not_zeroed { - D3D12_HEAP_FLAG_CREATE_NOT_ZEROED - } else { - d3d12::D3D12_HEAP_FLAG_NONE - }, - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; + pub(crate) fn create_texture_resource( + device: &crate::dx12::Device, + desc: &crate::TextureDescriptor, + raw_desc: d3d12::D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, + ) -> Result<(HRESULT, Option), crate::DeviceError> { + let location = MemoryLocation::GpuOnly; - Ok((hr, None)) -} + let name = desc.label.unwrap_or("Unlabeled texture"); -#[cfg(feature = "windows_rs")] -pub(crate) fn create_texture_resource( - device: &super::Device, - desc: &crate::TextureDescriptor, - raw_desc: d3d12::D3D12_RESOURCE_DESC, - resource: &mut WeakPtr, -) -> Result<(HRESULT, Option), crate::DeviceError> { - let location = MemoryLocation::GpuOnly; - - let name = desc.label.unwrap_or("Unlabeled texture"); - - // SAFETY: allocator exists when the windows_rs feature is enabled - let mut allocator = unsafe { device.mem_allocator.as_ref().unwrap_unchecked().lock() }; - let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( - allocator.allocator.device().as_winapi(), - &raw_desc, - name, - location, - ); - let allocation = allocator.allocator.allocate(&allocation_desc)?; - - let hr = unsafe { - device.raw.CreatePlacedResource( - allocation.heap().as_winapi() as *mut _, - allocation.offset(), + // SAFETY: allocator exists when the windows_rs feature is enabled + let mut allocator = device + .mem_allocator + .as_ref() + .strict_unwrap_unchecked() + .lock(); + let allocation_desc = AllocationCreateDesc::from_winapi_d3d12_resource_desc( + allocator.allocator.device().as_winapi(), &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), // clear value - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; + name, + location, + ); + let allocation = allocator.allocator.allocate(&allocation_desc)?; + + let hr = unsafe { + device.raw.CreatePlacedResource( + allocation.heap().as_winapi() as *mut _, + allocation.offset(), + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), // clear value + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; + + Ok((hr, Some(AllocationWrapper { allocation }))) + } + + pub(crate) fn free_buffer_allocation( + allocation: AllocationWrapper, + allocator: &Mutex, + ) { + match allocator.lock().allocator.free(allocation.allocation) { + Ok(_) => (), + // TODO: Don't panic here + Err(e) => panic!("Failed to destroy dx12 buffer, {}", e), + }; + } + + pub(crate) fn free_texture_allocation( + allocation: AllocationWrapper, + allocator: &Mutex, + ) { + match allocator.lock().allocator.free(allocation.allocation) { + Ok(_) => (), + // TODO: Don't panic here + Err(e) => panic!("Failed to destroy dx12 texture, {}", e), + }; + } - Ok((hr, Some(AllocationWrapper { allocation }))) + #[cfg(feature = "windows_rs")] + impl From for crate::DeviceError { + fn from(result: gpu_allocator::AllocationError) -> Self { + match result { + gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, + gpu_allocator::AllocationError::FailedToMap(e) => { + log::error!("DX12 gpu-allocator: Failed to map: {}", e); + Self::Lost + } + gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => { + log::error!("DX12 gpu-allocator: No Compatible Memory Type Found"); + Self::Lost + } + gpu_allocator::AllocationError::InvalidAllocationCreateDesc => { + log::error!("DX12 gpu-allocator: Invalid Allocation Creation Description"); + Self::Lost + } + gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => { + log::error!( + "DX12 gpu-allocator: Invalid Allocator Creation Description: {}", + e + ); + Self::Lost + } + gpu_allocator::AllocationError::Internal(e) => { + log::error!("DX12 gpu-allocator: Internal Error: {}", e); + Self::Lost + } + } + } + } } +// This exists to work around https://github.com/gfx-rs/wgpu/issues/3207 +// Currently this will work the older, slower way if the windows_rs feature is disabled, +// and will suballocate buffers using gpu_allocator if the windows_rs feature is enabled. #[cfg(not(feature = "windows_rs"))] -pub(crate) fn create_texture_resource( - device: &super::Device, - _desc: &crate::TextureDescriptor, - raw_desc: d3d12::D3D12_RESOURCE_DESC, - resource: &mut WeakPtr, -) -> Result<(HRESULT, Option), crate::DeviceError> { - let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { - Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, - CPUPageProperty: d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, - MemoryPoolPreference: match device.private_caps.memory_architecture { - super::MemoryArchitecture::NonUnified => d3d12::D3D12_MEMORY_POOL_L1, - super::MemoryArchitecture::Unified { .. } => d3d12::D3D12_MEMORY_POOL_L0, +mod allocation { + use native::WeakPtr; + use parking_lot::Mutex; + use std::ptr; + use winapi::{ + um::{ + d3d12::{self, ID3D12Resource}, + winnt::HRESULT, }, - CreationNodeMask: 0, - VisibleNodeMask: 0, + Interface, }; - let hr = unsafe { - device.raw.CreateCommittedResource( - &heap_properties, - if device.private_caps.heap_create_not_zeroed { - D3D12_HEAP_FLAG_CREATE_NOT_ZEROED + const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; // TODO: find the exact value + + #[derive(Debug)] + pub(crate) struct GpuAllocatorWrapper {} + + #[derive(Debug)] + pub(crate) struct AllocationWrapper {} + + pub(crate) fn create_allocator_wrapper( + _raw: &native::Device, + ) -> Result>, crate::DeviceError> { + Ok(None) + } + + pub(crate) fn create_buffer_resource( + device: &crate::dx12::Device, + desc: &crate::BufferDescriptor, + raw_desc: d3d12::D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, + ) -> Result<(HRESULT, Option), crate::DeviceError> { + let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ); + let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); + + let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { + Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, + CPUPageProperty: if is_cpu_read { + d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_BACK + } else if is_cpu_write { + d3d12::D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE } else { - d3d12::D3D12_HEAP_FLAG_NONE + d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE }, - &raw_desc, - d3d12::D3D12_RESOURCE_STATE_COMMON, - ptr::null(), // clear value - &d3d12::ID3D12Resource::uuidof(), - resource.mut_void(), - ) - }; + MemoryPoolPreference: match device.private_caps.memory_architecture { + crate::dx12::MemoryArchitecture::NonUnified if !is_cpu_read && !is_cpu_write => { + d3d12::D3D12_MEMORY_POOL_L1 + } + _ => d3d12::D3D12_MEMORY_POOL_L0, + }, + CreationNodeMask: 0, + VisibleNodeMask: 0, + }; - Ok((hr, None)) -} + let hr = unsafe { + device.raw.CreateCommittedResource( + &heap_properties, + if device.private_caps.heap_create_not_zeroed { + D3D12_HEAP_FLAG_CREATE_NOT_ZEROED + } else { + d3d12::D3D12_HEAP_FLAG_NONE + }, + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; -#[cfg(not(feature = "windows_rs"))] -pub(crate) fn free_buffer_allocation( - _allocation: AllocationWrapper, - _allocator: &Mutex, -) { - // No-op when not using gpu-allocator -} + Ok((hr, None)) + } -#[cfg(feature = "windows_rs")] -pub(crate) fn free_buffer_allocation( - allocation: AllocationWrapper, - allocator: &Mutex, -) { - match allocator.lock().allocator.free(allocation.allocation) { - Ok(_) => (), - // TODO: Don't panic here - Err(e) => panic!("Failed to destroy dx12 buffer, {}", e), - }; -} + pub(crate) fn create_texture_resource( + device: &crate::dx12::Device, + _desc: &crate::TextureDescriptor, + raw_desc: d3d12::D3D12_RESOURCE_DESC, + resource: &mut WeakPtr, + ) -> Result<(HRESULT, Option), crate::DeviceError> { + let heap_properties = d3d12::D3D12_HEAP_PROPERTIES { + Type: d3d12::D3D12_HEAP_TYPE_CUSTOM, + CPUPageProperty: d3d12::D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, + MemoryPoolPreference: match device.private_caps.memory_architecture { + crate::dx12::MemoryArchitecture::NonUnified => d3d12::D3D12_MEMORY_POOL_L1, + crate::dx12::MemoryArchitecture::Unified { .. } => d3d12::D3D12_MEMORY_POOL_L0, + }, + CreationNodeMask: 0, + VisibleNodeMask: 0, + }; -#[cfg(not(feature = "windows_rs"))] -pub(crate) fn free_texture_allocation( - _allocation: AllocationWrapper, - _allocator: &Mutex, -) { - // No-op when not using gpu-allocator -} + let hr = unsafe { + device.raw.CreateCommittedResource( + &heap_properties, + if device.private_caps.heap_create_not_zeroed { + D3D12_HEAP_FLAG_CREATE_NOT_ZEROED + } else { + d3d12::D3D12_HEAP_FLAG_NONE + }, + &raw_desc, + d3d12::D3D12_RESOURCE_STATE_COMMON, + ptr::null(), // clear value + &d3d12::ID3D12Resource::uuidof(), + resource.mut_void(), + ) + }; -#[cfg(feature = "windows_rs")] -pub(crate) fn free_texture_allocation( - allocation: AllocationWrapper, - allocator: &Mutex, -) { - match allocator.lock().allocator.free(allocation.allocation) { - Ok(_) => (), - // TODO: Don't panic here - Err(e) => panic!("Failed to destroy dx12 texture, {}", e), - }; -} + Ok((hr, None)) + } -#[cfg(feature = "windows_rs")] -impl From for crate::DeviceError { - fn from(result: gpu_allocator::AllocationError) -> Self { - match result { - gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, - gpu_allocator::AllocationError::FailedToMap(e) => { - log::error!("DX12 gpu-allocator: Failed to map: {}", e); - Self::Lost - } - gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => { - log::error!("DX12 gpu-allocator: No Compatible Memory Type Found"); - Self::Lost - } - gpu_allocator::AllocationError::InvalidAllocationCreateDesc => { - log::error!("DX12 gpu-allocator: Invalid Allocation Creation Description"); - Self::Lost - } - gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => { - log::error!( - "DX12 gpu-allocator: Invalid Allocator Creation Description: {}", - e - ); - Self::Lost - } - gpu_allocator::AllocationError::Internal(e) => { - log::error!("DX12 gpu-allocator: Internal Error: {}", e); - Self::Lost - } - } + pub(crate) fn free_buffer_allocation( + _allocation: AllocationWrapper, + _allocator: &Mutex, + ) { + // No-op when not using gpu-allocator + } + + pub(crate) fn free_texture_allocation( + _allocation: AllocationWrapper, + _allocator: &Mutex, + ) { + // No-op when not using gpu-allocator } } From 744bc0a1fe7f146ab203caa2b50f5157b2c32c9b Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 21:02:54 -0500 Subject: [PATCH 20/22] fmt --- wgpu-types/src/assertions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-types/src/assertions.rs b/wgpu-types/src/assertions.rs index 80a54c211e..8dc390c0ec 100644 --- a/wgpu-types/src/assertions.rs +++ b/wgpu-types/src/assertions.rs @@ -83,4 +83,4 @@ impl StrictAssertUnwrapExt for Result { strict_assert!(self.is_ok(), "Called strict_unwrap_unchecked on Err"); unsafe { self.unwrap_unchecked() } } -} \ No newline at end of file +} From 10ef37c38e2464ccdd35eca3ec941fed89df5244 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 21:12:41 -0500 Subject: [PATCH 21/22] comments on why suballocation.rs exists, point out which is the fast and which is the slow path --- wgpu-hal/src/dx12/suballocation.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dx12/suballocation.rs b/wgpu-hal/src/dx12/suballocation.rs index 6085d66566..62186a3964 100644 --- a/wgpu-hal/src/dx12/suballocation.rs +++ b/wgpu-hal/src/dx12/suballocation.rs @@ -3,6 +3,12 @@ pub(crate) use allocation::{ free_buffer_allocation, free_texture_allocation, AllocationWrapper, GpuAllocatorWrapper, }; +// This exists to work around https://github.com/gfx-rs/wgpu/issues/3207 +// Currently this will work the older, slower way if the windows_rs feature is disabled, +// and will use the fast path of suballocating buffers and textures using gpu_allocator if +// the windows_rs feature is enabled. + +// This is the fast path using gpu_allocator to suballocate buffers and textures. #[cfg(feature = "windows_rs")] mod allocation { use native::WeakPtr; @@ -191,9 +197,8 @@ mod allocation { } } -// This exists to work around https://github.com/gfx-rs/wgpu/issues/3207 -// Currently this will work the older, slower way if the windows_rs feature is disabled, -// and will suballocate buffers using gpu_allocator if the windows_rs feature is enabled. +// This is the older, slower path where it doesn't suballocate buffers. +// Tracking issue for when it can be removed: https://github.com/gfx-rs/wgpu/issues/3207 #[cfg(not(feature = "windows_rs"))] mod allocation { use native::WeakPtr; @@ -209,9 +214,11 @@ mod allocation { const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12::D3D12_HEAP_FLAG_NONE; // TODO: find the exact value + // Allocator isn't needed when not suballocating with gpu_allocator #[derive(Debug)] pub(crate) struct GpuAllocatorWrapper {} + // Allocations aren't needed when not suballocating with gpu_allocator #[derive(Debug)] pub(crate) struct AllocationWrapper {} From 719d26c6f2fb3f5d59def660b7c65e474ecf77b9 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 19 Dec 2022 22:26:48 -0500 Subject: [PATCH 22/22] default windows_rs enabled for wgpu-hal --- wgpu/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 0e1c259518..fe884d339b 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -137,7 +137,7 @@ hal = { workspace = true } hal = { workspace = true, features = ["renderdoc"] } [target.'cfg(windows)'.dependencies] -hal = { workspace = true, features = ["renderdoc"] } +hal = { workspace = true, features = ["renderdoc", "windows_rs"] } [target.'cfg(target_arch = "wasm32")'.dependencies.hal] workspace = true