Skip to content

Miscellaneous improvements in the D3D12 backend #7490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
1 change: 1 addition & 0 deletions wgpu-hal/src/auxil/dxgi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
pub mod conv;
pub mod exception;
pub mod factory;
pub mod name;
pub mod result;
pub mod time;
24 changes: 24 additions & 0 deletions wgpu-hal/src/auxil/dxgi/name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use windows::Win32::Graphics::Direct3D12::ID3D12Object;

use crate::auxil::dxgi::result::HResult;

/// Helper trait for setting the name of a D3D12 object.
///
/// This is implemented on all types that can be converted to an [`ID3D12Object`].
pub trait ObjectExt {
fn set_name(&self, name: &str) -> Result<(), crate::DeviceError>;
}

impl<T> ObjectExt for T
where
// Windows impls `From` for all parent interfaces, so we can use that to convert to ID3D12Object.
//
// This includes implementations for references.
for<'a> &'a ID3D12Object: From<&'a T>,
{
fn set_name(&self, name: &str) -> Result<(), crate::DeviceError> {
let name = windows::core::HSTRING::from(name);
let object: &ID3D12Object = self.into();
unsafe { object.SetName(&name).into_device_result("SetName") }
}
}
8 changes: 5 additions & 3 deletions wgpu-hal/src/dx12/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use windows_core::Interface;

use super::conv;
use crate::{
auxil::{self, dxgi::result::HResult as _},
auxil::{
self,
dxgi::{name::ObjectExt, result::HResult as _},
},
dx12::borrow_interface_temporarily,
AccelerationStructureEntries,
};
Expand Down Expand Up @@ -328,8 +331,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
};

if let Some(label) = label {
unsafe { list.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
list.set_name(label)?;
}

self.list = Some(list);
Expand Down
22 changes: 21 additions & 1 deletion wgpu-hal/src/dx12/conv.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use windows::Win32::Graphics::{Direct3D, Direct3D12};
use windows::Win32::Graphics::{Direct3D, Direct3D12, Dxgi};

pub fn map_buffer_usage_to_resource_flags(
usage: wgt::BufferUses,
Expand All @@ -12,6 +12,26 @@ pub fn map_buffer_usage_to_resource_flags(
flags
}

pub fn map_buffer_descriptor(
desc: &crate::BufferDescriptor<'_>,
) -> Direct3D12::D3D12_RESOURCE_DESC {
Direct3D12::D3D12_RESOURCE_DESC {
Dimension: Direct3D12::D3D12_RESOURCE_DIMENSION_BUFFER,
Alignment: 0,
Width: desc.size,
Height: 1,
DepthOrArraySize: 1,
MipLevels: 1,
Format: Dxgi::Common::DXGI_FORMAT_UNKNOWN,
SampleDesc: Dxgi::Common::DXGI_SAMPLE_DESC {
Count: 1,
Quality: 0,
},
Layout: Direct3D12::D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
Flags: map_buffer_usage_to_resource_flags(desc.usage),
}
}

pub fn map_texture_dimension(dim: wgt::TextureDimension) -> Direct3D12::D3D12_RESOURCE_DIMENSION {
match dim {
wgt::TextureDimension::D1 => Direct3D12::D3D12_RESOURCE_DIMENSION_TEXTURE1D,
Expand Down
145 changes: 39 additions & 106 deletions wgpu-hal/src/dx12/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ use windows::{

use super::{conv, descriptor, D3D12Lib};
use crate::{
auxil::{self, dxgi::result::HResult},
auxil::{
self,
dxgi::{name::ObjectExt, result::HResult},
},
dx12::{
borrow_optional_interface_temporarily, shader_compilation, suballocation,
DynamicStorageBufferOffsets, Event,
Expand Down Expand Up @@ -383,7 +386,10 @@ impl super::Device {
size,
mip_level_count,
sample_count,
allocation: suballocation::Allocation::none(suballocation::AllocationType::Texture),
allocation: suballocation::Allocation::none(
suballocation::AllocationType::Texture,
format.theoretical_memory_footprint(size),
),
}
}

Expand All @@ -394,7 +400,10 @@ impl super::Device {
super::Buffer {
resource,
size,
allocation: suballocation::Allocation::none(suballocation::AllocationType::Buffer),
allocation: suballocation::Allocation::none(
suballocation::AllocationType::Buffer,
size,
),
}
}
}
Expand All @@ -406,40 +415,17 @@ impl crate::Device for super::Device {
&self,
desc: &crate::BufferDescriptor,
) -> Result<super::Buffer, crate::DeviceError> {
let alloc_size = if desc.usage.contains(wgt::BufferUses::UNIFORM) {
desc.size
.next_multiple_of(Direct3D12::D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT.into())
} else {
desc.size
};
let mut desc = desc.clone();

let raw_desc = Direct3D12::D3D12_RESOURCE_DESC {
Dimension: Direct3D12::D3D12_RESOURCE_DIMENSION_BUFFER,
Alignment: 0,
Width: alloc_size,
Height: 1,
DepthOrArraySize: 1,
MipLevels: 1,
Format: Dxgi::Common::DXGI_FORMAT_UNKNOWN,
SampleDesc: Dxgi::Common::DXGI_SAMPLE_DESC {
Count: 1,
Quality: 0,
},
Layout: Direct3D12::D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
Flags: conv::map_buffer_usage_to_resource_flags(desc.usage),
};

let (resource, allocation) = suballocation::create_buffer(
suballocation::DeviceAllocationContext::from(self),
desc,
raw_desc,
)?;

if let Some(label) = desc.label {
unsafe { resource.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
if desc.usage.contains(wgt::BufferUses::UNIFORM) {
desc.size = desc
.size
.next_multiple_of(Direct3D12::D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT.into())
}

let (resource, allocation) =
suballocation::DeviceAllocationContext::from(self).create_buffer(&desc)?;

self.counters.buffers.add(1);

Ok(super::Buffer {
Expand All @@ -450,11 +436,8 @@ impl crate::Device for super::Device {
}

unsafe fn destroy_buffer(&self, buffer: super::Buffer) {
suballocation::free_resource(
suballocation::DeviceAllocationContext::from(self),
buffer.resource,
buffer.allocation,
);
suballocation::DeviceAllocationContext::from(self)
.free_resource(buffer.resource, buffer.allocation);

self.counters.buffers.sub(1);
}
Expand Down Expand Up @@ -515,16 +498,8 @@ impl crate::Device for super::Device {
Flags: conv::map_texture_usage_to_resource_flags(desc.usage),
};

let (resource, allocation) = suballocation::create_texture(
suballocation::DeviceAllocationContext::from(self),
desc,
raw_desc,
)?;

if let Some(label) = desc.label {
unsafe { resource.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
}
let (resource, allocation) =
suballocation::DeviceAllocationContext::from(self).create_texture(desc, raw_desc)?;

self.counters.textures.add(1);

Expand All @@ -540,11 +515,8 @@ impl crate::Device for super::Device {
}

unsafe fn destroy_texture(&self, texture: super::Texture) {
suballocation::free_resource(
suballocation::DeviceAllocationContext::from(self),
texture.resource,
texture.allocation,
);
suballocation::DeviceAllocationContext::from(self)
.free_resource(texture.resource, texture.allocation);

self.counters.textures.sub(1);
}
Expand Down Expand Up @@ -741,8 +713,7 @@ impl crate::Device for super::Device {
.into_device_result("Command allocator creation")?;

if let Some(label) = desc.label {
unsafe { allocator.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
allocator.set_name(label)?;
}

self.counters.command_encoders.add(1);
Expand Down Expand Up @@ -1336,8 +1307,7 @@ impl crate::Device for super::Device {
};

if let Some(label) = desc.label {
unsafe { raw.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
raw.set_name(label)?;
}

self.counters.pipeline_layouts.add(1);
Expand Down Expand Up @@ -1560,37 +1530,15 @@ impl crate::Device for super::Device {
};

let buffer_desc = crate::BufferDescriptor {
label: None,
label: Some(&label),
size: buffer_size,
usage: wgt::BufferUses::STORAGE_READ_ONLY | wgt::BufferUses::MAP_WRITE,
// D3D12 backend doesn't care about the memory flags
memory_flags: crate::MemoryFlags::empty(),
};

let raw_buffer_desc = Direct3D12::D3D12_RESOURCE_DESC {
Dimension: Direct3D12::D3D12_RESOURCE_DIMENSION_BUFFER,
Alignment: 0,
Width: buffer_size,
Height: 1,
DepthOrArraySize: 1,
MipLevels: 1,
Format: Dxgi::Common::DXGI_FORMAT_UNKNOWN,
SampleDesc: Dxgi::Common::DXGI_SAMPLE_DESC {
Count: 1,
Quality: 0,
},
Layout: Direct3D12::D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
Flags: Direct3D12::D3D12_RESOURCE_FLAG_NONE,
};

let (buffer, allocation) = suballocation::create_buffer(
suballocation::DeviceAllocationContext::from(self),
&buffer_desc,
raw_buffer_desc,
)?;

unsafe { buffer.SetName(&windows::core::HSTRING::from(&*label)) }
.into_device_result("SetName")?;
let (buffer, allocation) =
suballocation::DeviceAllocationContext::from(self).create_buffer(&buffer_desc)?;

let mut mapping = ptr::null_mut::<ffi::c_void>();
unsafe { buffer.Map(0, None, Some(&mut mapping)) }.into_device_result("Map")?;
Expand Down Expand Up @@ -1669,11 +1617,8 @@ impl crate::Device for super::Device {
}

if let Some(sampler_buffer) = group.sampler_index_buffer {
suballocation::free_resource(
suballocation::DeviceAllocationContext::from(self),
sampler_buffer.buffer,
sampler_buffer.allocation,
);
suballocation::DeviceAllocationContext::from(self)
.free_resource(sampler_buffer.buffer, sampler_buffer.allocation);
}

self.counters.bind_groups.sub(1);
Expand Down Expand Up @@ -1878,8 +1823,7 @@ impl crate::Device for super::Device {
};

if let Some(label) = desc.label {
unsafe { raw.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
raw.set_name(label)?;
}

self.counters.render_pipelines.add(1);
Expand Down Expand Up @@ -1942,8 +1886,7 @@ impl crate::Device for super::Device {
})?;

if let Some(label) = desc.label {
unsafe { raw.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
raw.set_name(label)?;
}

self.counters.compute_pipelines.add(1);
Expand Down Expand Up @@ -2001,8 +1944,7 @@ impl crate::Device for super::Device {
let raw = raw.ok_or(crate::DeviceError::Unexpected)?;

if let Some(label) = desc.label {
unsafe { raw.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
raw.set_name(label)?;
}

self.counters.query_sets.add(1);
Expand Down Expand Up @@ -2292,16 +2234,8 @@ impl crate::Device for super::Device {
Flags: Direct3D12::D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
};

let (resource, allocation) = suballocation::create_acceleration_structure(
suballocation::DeviceAllocationContext::from(self),
desc,
raw_desc,
)?;

if let Some(label) = desc.label {
unsafe { resource.SetName(&windows::core::HSTRING::from(label)) }
.into_device_result("SetName")?;
}
let (resource, allocation) = suballocation::DeviceAllocationContext::from(self)
.create_acceleration_structure(desc, raw_desc)?;

// for some reason there is no counter for acceleration structures

Expand All @@ -2315,8 +2249,7 @@ impl crate::Device for super::Device {
&self,
acceleration_structure: super::AccelerationStructure,
) {
suballocation::free_resource(
suballocation::DeviceAllocationContext::from(self),
suballocation::DeviceAllocationContext::from(self).free_resource(
acceleration_structure.resource,
acceleration_structure.allocation,
);
Expand Down
8 changes: 7 additions & 1 deletion wgpu-hal/src/dx12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,9 @@ unsafe impl Sync for CommandBuffer {}
#[derive(Debug)]
pub struct Buffer {
resource: Direct3D12::ID3D12Resource,
// While the allocation also has _a_ size, it may not
// be the same as the original size of the buffer,
// as the allocation size varies for assorted reasons.
size: wgt::BufferAddress,
allocation: suballocation::Allocation,
}
Expand Down Expand Up @@ -1375,7 +1378,10 @@ impl crate::Surface for Surface {
size: sc.size,
mip_level_count: 1,
sample_count: 1,
allocation: suballocation::Allocation::none(suballocation::AllocationType::Texture),
allocation: suballocation::Allocation::none(
suballocation::AllocationType::Texture,
sc.format.theoretical_memory_footprint(sc.size),
),
};
Ok(Some(crate::AcquiredSurfaceTexture {
texture,
Expand Down
Loading