diff --git a/CHANGELOG.md b/CHANGELOG.md index 67a296351..b97e03173 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,10 @@ Bottom level categories: #### Vulkan - Fix incorrect aspect in barriers when using emulated Stencil8 textures. By @cwfitzgerald in [#3833](https://github.com/gfx-rs/wgpu/pull/3833). +#### DX12 + +- Disable suballocation on Intel Iris(R) Xe. By @xiaopengli89 in [#3668](https://github.com/gfx-rs/wgpu/pull/3668) + ### Examples #### General diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 805d77376..e8f884176 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -200,6 +200,8 @@ impl super::Adapter { }, heap_create_not_zeroed: false, //TODO: winapi support for Options7 casting_fully_typed_format_supported, + // See https://github.com/gfx-rs/wgpu/issues/3552 + suballocation_supported: !info.name.contains("Iris(R) Xe"), }; // 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 7e1481857..cb72100a2 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -20,7 +20,11 @@ impl super::Device { library: &Arc, dx12_shader_compiler: wgt::Dx12Compiler, ) -> Result { - let mem_allocator = super::suballocation::create_allocator_wrapper(&raw)?; + let mem_allocator = if private_caps.suballocation_supported { + super::suballocation::create_allocator_wrapper(&raw)? + } else { + None + }; let dxc_container = match dx12_shader_compiler { wgt::Dx12Compiler::Dxc { diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 6cdf3ffe6..6ef148e4a 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -176,6 +176,7 @@ struct PrivateCapabilities { #[allow(unused)] // TODO: Exists until windows-rs is standard, then it can probably be removed? heap_create_not_zeroed: bool, casting_fully_typed_format_supported: bool, + suballocation_supported: bool, } #[derive(Default)] diff --git a/wgpu-hal/src/dx12/suballocation.rs b/wgpu-hal/src/dx12/suballocation.rs index 01ca997f2..7fb5ebd25 100644 --- a/wgpu-hal/src/dx12/suballocation.rs +++ b/wgpu-hal/src/dx12/suballocation.rs @@ -3,6 +3,11 @@ pub(crate) use allocation::{ free_buffer_allocation, free_texture_allocation, AllocationWrapper, GpuAllocatorWrapper, }; +#[cfg(not(feature = "windows_rs"))] +use committed as allocation; +#[cfg(feature = "windows_rs")] +use placed as 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 use the fast path of suballocating buffers and textures using gpu_allocator if @@ -10,7 +15,7 @@ pub(crate) use allocation::{ // This is the fast path using gpu_allocator to suballocate buffers and textures. #[cfg(feature = "windows_rs")] -mod allocation { +mod placed { use d3d12::WeakPtr; use parking_lot::Mutex; use std::ptr; @@ -63,6 +68,13 @@ mod allocation { ) -> 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); + + // It's a workaround for Intel Xe drivers. + if !device.private_caps.suballocation_supported { + return super::committed::create_buffer_resource(device, desc, raw_desc, resource) + .map(|(hr, _)| (hr, None)); + } + let location = match (is_cpu_read, is_cpu_write) { (true, true) => MemoryLocation::CpuToGpu, (true, false) => MemoryLocation::GpuToCpu, @@ -111,6 +123,12 @@ mod allocation { raw_desc: d3d12_ty::D3D12_RESOURCE_DESC, resource: &mut WeakPtr, ) -> Result<(HRESULT, Option), crate::DeviceError> { + // It's a workaround for Intel Xe drivers. + if !device.private_caps.suballocation_supported { + return super::committed::create_texture_resource(device, desc, raw_desc, resource) + .map(|(hr, _)| (hr, None)); + } + let location = MemoryLocation::GpuOnly; let name = desc.label.unwrap_or("Unlabeled texture"); @@ -168,7 +186,6 @@ mod allocation { }; } - #[cfg(feature = "windows_rs")] impl From for crate::DeviceError { fn from(result: gpu_allocator::AllocationError) -> Self { match result { @@ -203,8 +220,7 @@ mod allocation { // 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 { +mod committed { use d3d12::WeakPtr; use parking_lot::Mutex; use std::ptr; @@ -216,7 +232,8 @@ mod allocation { Interface, }; - const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: u32 = d3d12_ty::D3D12_HEAP_FLAG_NONE; // TODO: find the exact value + // https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_heap_flags + const D3D12_HEAP_FLAG_CREATE_NOT_ZEROED: d3d12_ty::D3D12_HEAP_FLAGS = 0x1000; // Allocator isn't needed when not suballocating with gpu_allocator #[derive(Debug)] @@ -226,6 +243,7 @@ mod allocation { #[derive(Debug)] pub(crate) struct AllocationWrapper {} + #[allow(unused)] pub(crate) fn create_allocator_wrapper( _raw: &d3d12::Device, ) -> Result>, crate::DeviceError> { @@ -315,6 +333,7 @@ mod allocation { Ok((hr, None)) } + #[allow(unused)] pub(crate) fn free_buffer_allocation( _allocation: AllocationWrapper, _allocator: &Mutex, @@ -322,6 +341,7 @@ mod allocation { // No-op when not using gpu-allocator } + #[allow(unused)] pub(crate) fn free_texture_allocation( _allocation: AllocationWrapper, _allocator: &Mutex,