Port to d3d12 0.7 with ownership

This replaces the WeakPtr usage with ComPtr which is no longer
Copy. This means we need to do a bunch of clone()s and take some
things as references.
This commit is contained in:
Jeff Muizelaar 2023-07-13 20:57:11 -04:00 committed by Jim Blandy
parent 80d19d890c
commit 1161a22f4f
14 changed files with 130 additions and 230 deletions

7
Cargo.lock generated
View File

@ -481,10 +481,11 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
[[package]]
name = "d3d12"
version = "0.6.0"
source = "git+https://github.com/gfx-rs/d3d12-rs?rev=b940b1d71#b940b1d71ab7083ae80eec697872672dc1f2bd32"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20"
dependencies = [
"bitflags 1.3.2",
"bitflags 2.3.2",
"libloading 0.7.4",
"winapi",
]

View File

@ -97,7 +97,7 @@ gpu-allocator = { version = "0.22", default_features = false, features = ["d3d12
hassle-rs = { version = "0.10", optional = true }
winapi = { version = "0.3", features = ["profileapi", "libloaderapi", "windef", "winuser", "dcomp"] }
d3d12 = { version = "0.6.0", git = "https://github.com/gfx-rs/d3d12-rs", rev = "b940b1d71", features = ["libloading"], optional = true }
d3d12 = { version = "0.7", features = ["libloading"], optional = true }
[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies]
# backend: Metal

View File

@ -20,7 +20,7 @@ pub fn enumerate_adapters(factory: d3d12::DxgiFactory) -> Vec<d3d12::DxgiAdapter
if let Some(factory6) = factory.as_factory6() {
profiling::scope!("IDXGIFactory6::EnumAdapterByGpuPreference");
// We're already at dxgi1.6, we can grab IDXGIAdapater4 directly
let mut adapter4 = d3d12::WeakPtr::<dxgi1_6::IDXGIAdapter4>::null();
let mut adapter4 = d3d12::ComPtr::<dxgi1_6::IDXGIAdapter4>::null();
let hr = unsafe {
factory6.EnumAdapterByGpuPreference(
cur_index,
@ -43,7 +43,7 @@ pub fn enumerate_adapters(factory: d3d12::DxgiFactory) -> Vec<d3d12::DxgiAdapter
}
profiling::scope!("IDXGIFactory1::EnumAdapters1");
let mut adapter1 = d3d12::WeakPtr::<dxgi::IDXGIAdapter1>::null();
let mut adapter1 = d3d12::ComPtr::<dxgi::IDXGIAdapter1>::null();
let hr = unsafe { factory.EnumAdapters1(cur_index, adapter1.mut_self()) };
if hr == winerror::DXGI_ERROR_NOT_FOUND {
@ -60,7 +60,6 @@ pub fn enumerate_adapters(factory: d3d12::DxgiFactory) -> Vec<d3d12::DxgiAdapter
unsafe {
match adapter1.cast::<dxgi1_4::IDXGIAdapter3>().into_result() {
Ok(adapter3) => {
adapter1.destroy();
adapters.push(d3d12::DxgiAdapter::Adapter3(adapter3));
continue;
}
@ -74,7 +73,6 @@ pub fn enumerate_adapters(factory: d3d12::DxgiFactory) -> Vec<d3d12::DxgiAdapter
unsafe {
match adapter1.cast::<dxgi1_2::IDXGIAdapter2>().into_result() {
Ok(adapter2) => {
adapter1.destroy();
adapters.push(d3d12::DxgiAdapter::Adapter2(adapter2));
continue;
}
@ -107,8 +105,7 @@ pub fn create_factory(
// we check for whether it exists first.
match lib_dxgi.get_debug_interface1() {
Ok(pair) => match pair.into_result() {
Ok(debug_controller) => {
unsafe { debug_controller.destroy() };
Ok(_debug_controller) => {
factory_flags |= d3d12::FactoryCreationFlags::DEBUG;
}
Err(err) => {
@ -151,9 +148,6 @@ pub fn create_factory(
let factory6 = unsafe { factory4.cast::<dxgi1_6::IDXGIFactory6>().into_result() };
match factory6 {
Ok(factory6) => {
unsafe {
factory4.destroy();
}
return Ok((lib_dxgi, d3d12::DxgiFactory::Factory6(factory6)));
}
// If we require factory6, hard error.
@ -189,9 +183,6 @@ pub fn create_factory(
let factory2 = unsafe { factory1.cast::<dxgi1_2::IDXGIFactory2>().into_result() };
match factory2 {
Ok(factory2) => {
unsafe {
factory1.destroy();
}
return Ok((lib_dxgi, d3d12::DxgiFactory::Factory2(factory2)));
}
// If we require factory2, hard error.

View File

@ -38,7 +38,7 @@ impl crate::Instance<super::Api> for super::Instance {
}
unsafe fn enumerate_adapters(&self) -> Vec<crate::ExposedAdapter<super::Api>> {
let adapters = auxil::dxgi::factory::enumerate_adapters(self.factory);
let adapters = auxil::dxgi::factory::enumerate_adapters(self.factory.clone());
adapters
.into_iter()

View File

@ -63,7 +63,7 @@ impl D3D11Lib {
d3dcommon::D3D_FEATURE_LEVEL_9_1,
];
let mut device = d3d12::WeakPtr::<d3d11::ID3D11Device>::null();
let mut device = d3d12::ComPtr::<d3d11::ID3D11Device>::null();
let mut feature_level: d3dcommon::D3D_FEATURE_LEVEL = 0;
// We need to try this twice. If the first time fails due to E_INVALIDARG
@ -117,7 +117,6 @@ impl D3D11Lib {
unsafe {
match device.cast::<d3d11_2::ID3D11Device2>().into_result() {
Ok(device2) => {
device.destroy();
return Some((super::D3D11Device::Device2(device2), feature_level));
}
Err(hr) => {
@ -130,7 +129,6 @@ impl D3D11Lib {
unsafe {
match device.cast::<d3d11_1::ID3D11Device1>().into_result() {
Ok(device1) => {
device.destroy();
return Some((super::D3D11Device::Device1(device1), feature_level));
}
Err(hr) => {

View File

@ -57,7 +57,7 @@ unsafe impl Send for Adapter {}
unsafe impl Sync for Adapter {}
d3d12::weak_com_inheritance_chain! {
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
enum D3D11Device {
Device(d3d11::ID3D11Device), from_device, as_device, device;
Device1(d3d11_1::ID3D11Device1), from_device1, as_device1, unwrap_device1;

View File

@ -21,9 +21,6 @@ impl Drop for super::Adapter {
self.report_live_objects();
}
}
unsafe {
self.raw.destroy();
}
}
}
@ -39,7 +36,6 @@ impl super::Adapter {
d3d12sdklayers::D3D12_RLDO_SUMMARY | d3d12sdklayers::D3D12_RLDO_IGNORE_INTERNAL,
)
};
unsafe { debug_device.destroy() };
}
}
@ -57,7 +53,7 @@ impl super::Adapter {
// Create the device so that we can get the capabilities.
let device = {
profiling::scope!("ID3D12Device::create_device");
match library.create_device(*adapter, d3d12::FeatureLevel::L11_0) {
match library.create_device(&adapter, d3d12::FeatureLevel::L11_0) {
Ok(pair) => match pair.into_result() {
Ok(device) => device,
Err(err) => {
@ -396,8 +392,8 @@ impl crate::Adapter<super::Api> for super::Adapter {
};
let device = super::Device::new(
self.device,
queue,
self.device.clone(),
queue.clone(),
self.private_caps,
&self.library,
self.dx12_shader_compiler.clone(),

View File

@ -61,7 +61,7 @@ impl super::Temp {
impl super::CommandEncoder {
unsafe fn begin_pass(&mut self, kind: super::PassKind, label: crate::Label) {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
self.pass.kind = kind;
if let Some(label) = label {
let (wide_label, size) = self.temp.prepare_marker(label);
@ -70,11 +70,14 @@ impl super::CommandEncoder {
}
self.pass.dirty_root_elements = 0;
self.pass.dirty_vertex_buffers = 0;
list.set_descriptor_heaps(&[self.shared.heap_views.raw, self.shared.heap_samplers.raw]);
list.set_descriptor_heaps(&[
self.shared.heap_views.raw.clone(),
self.shared.heap_samplers.raw.clone(),
]);
}
unsafe fn end_pass(&mut self) {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
list.set_descriptor_heaps(&[]);
if self.pass.has_label {
unsafe { list.EndEvent() };
@ -84,7 +87,7 @@ impl super::CommandEncoder {
unsafe fn prepare_draw(&mut self, base_vertex: i32, base_instance: u32) {
while self.pass.dirty_vertex_buffers != 0 {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
let index = self.pass.dirty_vertex_buffers.trailing_zeros();
self.pass.dirty_vertex_buffers ^= 1 << index;
unsafe {
@ -146,7 +149,7 @@ impl super::CommandEncoder {
use super::{BufferViewKind as Bvk, PassKind as Pk};
while self.pass.dirty_root_elements != 0 {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
let index = self.pass.dirty_root_elements.trailing_zeros();
self.pass.dirty_root_elements ^= 1 << index;
@ -232,14 +235,10 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
let list = loop {
if let Some(list) = self.free_lists.pop() {
let reset_result = list
.reset(self.allocator, d3d12::PipelineState::null())
.reset(&self.allocator, d3d12::PipelineState::null())
.into_result();
if reset_result.is_ok() {
break Some(list);
} else {
unsafe {
list.destroy();
}
}
} else {
break None;
@ -252,7 +251,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
self.device
.create_graphics_command_list(
d3d12::CmdListType::Direct,
self.allocator,
&self.allocator,
d3d12::PipelineState::null(),
0,
)
@ -273,10 +272,6 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
if let Some(list) = self.list.take() {
if list.close().into_result().is_ok() {
self.free_lists.push(list);
} else {
unsafe {
list.destroy();
}
}
}
}
@ -289,10 +284,6 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
for cmd_buf in command_buffers {
if cmd_buf.closed {
self.free_lists.push(cmd_buf.raw);
} else {
unsafe {
cmd_buf.raw.destroy();
}
}
}
self.allocator.reset();
@ -304,7 +295,10 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
{
self.temp.barriers.clear();
log::trace!("List {:p} buffer transitions", self.list.unwrap().as_ptr());
log::trace!(
"List {:p} buffer transitions",
self.list.as_ref().unwrap().as_ptr()
);
for barrier in barriers {
log::trace!(
"\t{:p}: usage {:?}..{:?}",
@ -347,6 +341,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
if !self.temp.barriers.is_empty() {
unsafe {
self.list
.as_ref()
.unwrap()
.ResourceBarrier(self.temp.barriers.len() as u32, self.temp.barriers.as_ptr())
};
@ -359,7 +354,10 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
{
self.temp.barriers.clear();
log::trace!("List {:p} texture transitions", self.list.unwrap().as_ptr());
log::trace!(
"List {:p} texture transitions",
self.list.as_ref().unwrap().as_ptr()
);
for barrier in barriers {
log::trace!(
"\t{:p}: usage {:?}..{:?}, range {:?}",
@ -442,6 +440,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
if !self.temp.barriers.is_empty() {
unsafe {
self.list
.as_ref()
.unwrap()
.ResourceBarrier(self.temp.barriers.len() as u32, self.temp.barriers.as_ptr())
};
@ -449,7 +448,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
unsafe fn clear_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange) {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
let mut offset = range.start;
while offset < range.end {
let size = super::ZERO_BUFFER_SIZE.min(range.end - offset);
@ -474,7 +473,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) where
T: Iterator<Item = crate::BufferCopy>,
{
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
for r in regions {
unsafe {
list.CopyBufferRegion(
@ -497,7 +496,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) where
T: Iterator<Item = crate::TextureCopy>,
{
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
let mut src_location = d3d12_ty::D3D12_TEXTURE_COPY_LOCATION {
pResource: src.resource.as_mut_ptr(),
Type: d3d12_ty::D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
@ -539,7 +538,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) where
T: Iterator<Item = crate::BufferTextureCopy>,
{
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
let mut src_location = d3d12_ty::D3D12_TEXTURE_COPY_LOCATION {
pResource: src.resource.as_mut_ptr(),
Type: d3d12_ty::D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
@ -581,7 +580,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) where
T: Iterator<Item = crate::BufferTextureCopy>,
{
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
let mut src_location = d3d12_ty::D3D12_TEXTURE_COPY_LOCATION {
pResource: src.resource.as_mut_ptr(),
Type: d3d12_ty::D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
@ -608,6 +607,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn begin_query(&mut self, set: &super::QuerySet, index: u32) {
unsafe {
self.list
.as_ref()
.unwrap()
.BeginQuery(set.raw.as_mut_ptr(), set.raw_ty, index)
};
@ -615,13 +615,14 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn end_query(&mut self, set: &super::QuerySet, index: u32) {
unsafe {
self.list
.as_ref()
.unwrap()
.EndQuery(set.raw.as_mut_ptr(), set.raw_ty, index)
};
}
unsafe fn write_timestamp(&mut self, set: &super::QuerySet, index: u32) {
unsafe {
self.list.unwrap().EndQuery(
self.list.as_ref().unwrap().EndQuery(
set.raw.as_mut_ptr(),
d3d12_ty::D3D12_QUERY_TYPE_TIMESTAMP,
index,
@ -640,7 +641,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
_stride: wgt::BufferSize,
) {
unsafe {
self.list.unwrap().ResolveQueryData(
self.list.as_ref().unwrap().ResolveQueryData(
set.raw.as_mut_ptr(),
set.raw_ty,
range.start,
@ -675,7 +676,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
};
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
unsafe {
list.OMSetRenderTargets(
desc.color_attachments.len() as u32,
@ -699,8 +700,8 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
if let Some(ref target) = cat.resolve_target {
self.pass.resolves.push(super::PassResolve {
src: cat.target.view.target_base,
dst: target.view.target_base,
src: cat.target.view.target_base.clone(),
dst: target.view.target_base.clone(),
format: target.view.raw_format,
});
}
@ -752,7 +753,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn end_render_pass(&mut self) {
if !self.pass.resolves.is_empty() {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap();
self.temp.barriers.clear();
// All the targets are expected to be in `COLOR_TARGET` state,
@ -902,6 +903,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
let (wide_label, size) = self.temp.prepare_marker(label);
unsafe {
self.list
.as_ref()
.unwrap()
.SetMarker(0, wide_label.as_ptr() as *const _, size)
};
@ -910,24 +912,25 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
let (wide_label, size) = self.temp.prepare_marker(group_label);
unsafe {
self.list
.as_ref()
.unwrap()
.BeginEvent(0, wide_label.as_ptr() as *const _, size)
};
}
unsafe fn end_debug_marker(&mut self) {
unsafe { self.list.unwrap().EndEvent() }
unsafe { self.list.as_ref().unwrap().EndEvent() }
}
unsafe fn set_render_pipeline(&mut self, pipeline: &super::RenderPipeline) {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap().clone();
if self.pass.layout.signature != pipeline.layout.signature {
// D3D12 requires full reset on signature change
list.set_graphics_root_signature(pipeline.layout.signature);
list.set_graphics_root_signature(&pipeline.layout.signature);
self.reset_signature(&pipeline.layout);
};
list.set_pipeline_state(pipeline.raw);
list.set_pipeline_state(&pipeline.raw);
unsafe { list.IASetPrimitiveTopology(pipeline.topology) };
for (index, (vb, &stride)) in self
@ -951,7 +954,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
binding: crate::BufferBinding<'a, super::Api>,
format: wgt::IndexFormat,
) {
self.list.unwrap().set_index_buffer(
self.list.as_ref().unwrap().set_index_buffer(
binding.resolve_address(),
binding.resolve_size() as u32,
auxil::dxgi::conv::map_index_format(format),
@ -977,7 +980,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
MinDepth: depth_range.start,
MaxDepth: depth_range.end,
};
unsafe { self.list.unwrap().RSSetViewports(1, &raw_vp) };
unsafe { self.list.as_ref().unwrap().RSSetViewports(1, &raw_vp) };
}
unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) {
let raw_rect = d3d12_ty::D3D12_RECT {
@ -986,13 +989,13 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
right: (rect.x + rect.w) as i32,
bottom: (rect.y + rect.h) as i32,
};
unsafe { self.list.unwrap().RSSetScissorRects(1, &raw_rect) };
unsafe { self.list.as_ref().unwrap().RSSetScissorRects(1, &raw_rect) };
}
unsafe fn set_stencil_reference(&mut self, value: u32) {
self.list.unwrap().set_stencil_reference(value);
self.list.as_ref().unwrap().set_stencil_reference(value);
}
unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) {
self.list.unwrap().set_blend_factor(*color);
self.list.as_ref().unwrap().set_blend_factor(*color);
}
unsafe fn draw(
@ -1003,9 +1006,12 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
instance_count: u32,
) {
unsafe { self.prepare_draw(start_vertex as i32, start_instance) };
self.list
.unwrap()
.draw(vertex_count, instance_count, start_vertex, start_instance);
self.list.as_ref().unwrap().draw(
vertex_count,
instance_count,
start_vertex,
start_instance,
);
}
unsafe fn draw_indexed(
&mut self,
@ -1016,7 +1022,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
instance_count: u32,
) {
unsafe { self.prepare_draw(base_vertex, start_instance) };
self.list.unwrap().draw_indexed(
self.list.as_ref().unwrap().draw_indexed(
index_count,
instance_count,
start_index,
@ -1032,7 +1038,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) {
unsafe { self.prepare_draw(0, 0) };
unsafe {
self.list.unwrap().ExecuteIndirect(
self.list.as_ref().unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw.as_mut_ptr(),
draw_count,
buffer.resource.as_mut_ptr(),
@ -1050,7 +1056,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) {
unsafe { self.prepare_draw(0, 0) };
unsafe {
self.list.unwrap().ExecuteIndirect(
self.list.as_ref().unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw_indexed.as_mut_ptr(),
draw_count,
buffer.resource.as_mut_ptr(),
@ -1070,7 +1076,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) {
unsafe { self.prepare_draw(0, 0) };
unsafe {
self.list.unwrap().ExecuteIndirect(
self.list.as_ref().unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw.as_mut_ptr(),
max_count,
buffer.resource.as_mut_ptr(),
@ -1090,7 +1096,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
) {
unsafe { self.prepare_draw(0, 0) };
unsafe {
self.list.unwrap().ExecuteIndirect(
self.list.as_ref().unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw_indexed.as_mut_ptr(),
max_count,
buffer.resource.as_mut_ptr(),
@ -1111,26 +1117,26 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) {
let list = self.list.unwrap();
let list = self.list.as_ref().unwrap().clone();
if self.pass.layout.signature != pipeline.layout.signature {
// D3D12 requires full reset on signature change
list.set_compute_root_signature(pipeline.layout.signature);
list.set_compute_root_signature(&pipeline.layout.signature);
self.reset_signature(&pipeline.layout);
};
list.set_pipeline_state(pipeline.raw);
list.set_pipeline_state(&pipeline.raw);
}
unsafe fn dispatch(&mut self, count: [u32; 3]) {
self.prepare_dispatch(count);
self.list.unwrap().dispatch(count);
self.list.as_ref().unwrap().dispatch(count);
}
unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) {
self.prepare_dispatch([0; 3]);
//TODO: update special constants indirectly
unsafe {
self.list.unwrap().ExecuteIndirect(
self.list.as_ref().unwrap().ExecuteIndirect(
self.shared.cmd_signatures.dispatch.as_mut_ptr(),
1,
buffer.resource.as_mut_ptr(),

View File

@ -54,7 +54,7 @@ impl GeneralHeap {
};
Ok(Self {
raw,
raw: raw.clone(),
ty,
handle_size: device.get_descriptor_increment_size(ty) as u64,
total_handles,
@ -106,7 +106,7 @@ impl GeneralHeap {
/// Fixed-size free-list allocator for CPU descriptors.
struct FixedSizeHeap {
raw: d3d12::DescriptorHeap,
_raw: d3d12::DescriptorHeap,
/// Bit flag representation of available handles in the heap.
///
/// 0 - Occupied
@ -117,7 +117,7 @@ struct FixedSizeHeap {
}
impl FixedSizeHeap {
fn new(device: d3d12::Device, ty: d3d12::DescriptorHeapType) -> Self {
fn new(device: &d3d12::Device, ty: d3d12::DescriptorHeapType) -> Self {
let (heap, _hr) = device.create_descriptor_heap(
HEAP_SIZE_FIXED as _,
ty,
@ -129,7 +129,7 @@ impl FixedSizeHeap {
handle_size: device.get_descriptor_increment_size(ty) as _,
availability: !0, // all free!
start: heap.start_cpu_descriptor(),
raw: heap,
_raw: heap,
}
}
@ -155,10 +155,6 @@ impl FixedSizeHeap {
fn is_full(&self) -> bool {
self.availability == 0
}
unsafe fn destroy(&self) {
unsafe { self.raw.destroy() };
}
}
#[derive(Clone, Copy)]
@ -201,7 +197,7 @@ impl CpuPool {
.unwrap_or_else(|| {
// Allocate a new heap
let id = self.heaps.len();
self.heaps.push(FixedSizeHeap::new(self.device, self.ty));
self.heaps.push(FixedSizeHeap::new(&self.device, self.ty));
self.avaliable_heap_indices.insert(id);
id
});
@ -222,16 +218,10 @@ impl CpuPool {
self.heaps[handle.heap_index].free_handle(handle.raw);
self.avaliable_heap_indices.insert(handle.heap_index);
}
pub(super) unsafe fn destroy(&self) {
for heap in &self.heaps {
unsafe { heap.destroy() };
}
}
}
pub(super) struct CpuHeapInner {
pub raw: d3d12::DescriptorHeap,
pub _raw: d3d12::DescriptorHeap,
pub stage: Vec<d3d12::CpuDescriptor>,
}
@ -258,7 +248,7 @@ impl CpuHeap {
Ok(Self {
inner: Mutex::new(CpuHeapInner {
raw,
_raw: raw.clone(),
stage: Vec::new(),
}),
start: raw.start_cpu_descriptor(),
@ -272,10 +262,6 @@ impl CpuHeap {
ptr: self.start.ptr + (self.handle_size * index) as usize,
}
}
pub(super) unsafe fn destroy(self) {
unsafe { self.inner.into_inner().raw.destroy() };
}
}
impl fmt::Debug for CpuHeap {

View File

@ -124,23 +124,23 @@ impl super::Device {
.into_device_result("Command (dispatch) signature creation")?,
},
heap_views: descriptor::GeneralHeap::new(
raw,
raw.clone(),
d3d12::DescriptorHeapType::CbvSrvUav,
capacity_views,
)?,
heap_samplers: descriptor::GeneralHeap::new(
raw,
raw.clone(),
d3d12::DescriptorHeapType::Sampler,
capacity_samplers,
)?,
};
let mut rtv_pool = descriptor::CpuPool::new(raw, d3d12::DescriptorHeapType::Rtv);
let mut rtv_pool = descriptor::CpuPool::new(raw.clone(), d3d12::DescriptorHeapType::Rtv);
let null_rtv_handle = rtv_pool.alloc_handle();
// A null pResource is used to initialize a null descriptor,
// which guarantees D3D11-like null binding behavior (reading 0s, writes are discarded)
raw.create_render_target_view(
d3d12::WeakPtr::null(),
d3d12::ComPtr::null(),
&d3d12::RenderTargetViewDesc::texture_2d(
winapi::shared::dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM,
0,
@ -150,7 +150,7 @@ impl super::Device {
);
Ok(super::Device {
raw,
raw: raw.clone(),
present_queue,
idler: super::Idler {
fence: idle_fence,
@ -160,11 +160,11 @@ impl super::Device {
shared: Arc::new(shared),
rtv_pool: Mutex::new(rtv_pool),
dsv_pool: Mutex::new(descriptor::CpuPool::new(
raw,
raw.clone(),
d3d12::DescriptorHeapType::Dsv,
)),
srv_uav_pool: Mutex::new(descriptor::CpuPool::new(
raw,
raw.clone(),
d3d12::DescriptorHeapType::CbvSrvUav,
)),
sampler_pool: Mutex::new(descriptor::CpuPool::new(
@ -188,7 +188,7 @@ impl super::Device {
let value = cur_value + 1;
log::info!("Waiting for idle with value {}", value);
self.present_queue.signal(self.idler.fence, value);
self.present_queue.signal(&self.idler.fence, value);
let hr = self
.idler
.fence
@ -313,16 +313,9 @@ impl super::Device {
}
impl crate::Device<super::Api> for super::Device {
unsafe fn exit(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() };
unsafe { self.srv_uav_pool.into_inner().destroy() };
unsafe { self.sampler_pool.into_inner().destroy() };
unsafe { self.shared.destroy() };
unsafe { self.idler.destroy() };
self.mem_allocator = None;
unsafe { queue.raw.destroy() };
}
unsafe fn create_buffer(
@ -369,7 +362,6 @@ impl crate::Device<super::Api> for super::Device {
}
unsafe fn destroy_buffer(&self, mut buffer: super::Buffer) {
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() {
super::suballocation::free_buffer_allocation(
@ -455,7 +447,6 @@ impl crate::Device<super::Api> for super::Device {
}
unsafe fn destroy_texture(&self, mut texture: super::Texture) {
unsafe { texture.resource.destroy() };
if let Some(alloc) = texture.allocation.take() {
super::suballocation::free_texture_allocation(
alloc,
@ -476,7 +467,7 @@ impl crate::Device<super::Api> for super::Device {
raw_format: view_desc.rtv_dsv_format,
aspects: view_desc.aspects,
target_base: (
texture.resource,
texture.resource.clone(),
texture.calc_subresource(desc.range.base_mip_level, desc.range.base_array_layer, 0),
),
handle_srv: if desc.usage.intersects(crate::TextureUses::RESOURCE) {
@ -646,7 +637,7 @@ impl crate::Device<super::Api> for super::Device {
Ok(super::CommandEncoder {
allocator,
device: self.raw,
device: self.raw.clone(),
shared: Arc::clone(&self.shared),
null_rtv_handle: self.null_rtv_handle,
list: None,
@ -658,12 +649,7 @@ impl crate::Device<super::Api> for super::Device {
unsafe fn destroy_command_encoder(&self, encoder: super::CommandEncoder) {
if let Some(list) = encoder.list {
list.close();
unsafe { list.destroy() };
}
for list in encoder.free_lists {
unsafe { list.destroy() };
}
unsafe { encoder.allocator.destroy() };
}
unsafe fn create_bind_group_layout(
@ -691,7 +677,7 @@ impl crate::Device<super::Api> for super::Device {
entries: desc.entries.to_vec(),
cpu_heap_views: if num_views != 0 {
let heap = descriptor::CpuHeap::new(
self.raw,
self.raw.clone(),
d3d12::DescriptorHeapType::CbvSrvUav,
num_views,
)?;
@ -701,7 +687,7 @@ impl crate::Device<super::Api> for super::Device {
},
cpu_heap_samplers: if num_samplers != 0 {
let heap = descriptor::CpuHeap::new(
self.raw,
self.raw.clone(),
d3d12::DescriptorHeapType::Sampler,
num_samplers,
)?;
@ -712,14 +698,7 @@ impl crate::Device<super::Api> for super::Device {
copy_counts: vec![1; num_views.max(num_samplers) as usize],
})
}
unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) {
if let Some(cpu_heap) = bg_layout.cpu_heap_views {
unsafe { cpu_heap.destroy() };
}
if let Some(cpu_heap) = bg_layout.cpu_heap_samplers {
unsafe { cpu_heap.destroy() };
}
}
unsafe fn destroy_bind_group_layout(&self, _bg_layout: super::BindGroupLayout) {}
unsafe fn create_pipeline_layout(
&self,
@ -1043,7 +1022,6 @@ impl crate::Device<super::Api> for super::Device {
"Root signature serialization error: {:?}",
unsafe { error.as_c_str() }.to_str().unwrap()
);
unsafe { error.destroy() };
return Err(crate::DeviceError::Lost);
}
@ -1051,7 +1029,6 @@ impl crate::Device<super::Api> for super::Device {
.raw
.create_root_signature(blob, 0)
.into_device_result("Root signature creation")?;
unsafe { blob.destroy() };
log::debug!("\traw = {:?}", raw);
@ -1083,9 +1060,7 @@ impl crate::Device<super::Api> for super::Device {
},
})
}
unsafe fn destroy_pipeline_layout(&self, pipeline_layout: super::PipelineLayout) {
unsafe { pipeline_layout.shared.signature.destroy() };
}
unsafe fn destroy_pipeline_layout(&self, _pipeline_layout: super::PipelineLayout) {}
unsafe fn create_bind_group(
&self,
@ -1222,7 +1197,7 @@ impl crate::Device<super::Api> for super::Device {
Some(inner) => {
let dual = unsafe {
descriptor::upload(
self.raw,
self.raw.clone(),
&inner,
&self.shared.heap_views,
&desc.layout.copy_counts,
@ -1236,7 +1211,7 @@ impl crate::Device<super::Api> for super::Device {
Some(inner) => {
let dual = unsafe {
descriptor::upload(
self.raw,
self.raw.clone(),
&inner,
&self.shared.heap_samplers,
&desc.layout.copy_counts,
@ -1462,9 +1437,7 @@ impl crate::Device<super::Api> for super::Device {
vertex_strides,
})
}
unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) {
unsafe { pipeline.raw.destroy() };
}
unsafe fn destroy_render_pipeline(&self, _pipeline: super::RenderPipeline) {}
unsafe fn create_compute_pipeline(
&self,
@ -1475,7 +1448,7 @@ impl crate::Device<super::Api> for super::Device {
let pair = {
profiling::scope!("ID3D12Device::CreateComputePipelineState");
self.raw.create_compute_pipeline_state(
desc.layout.shared.signature,
&desc.layout.shared.signature,
blob_cs.create_native_shader(),
0,
d3d12::CachedPSO::null(),
@ -1499,9 +1472,7 @@ impl crate::Device<super::Api> for super::Device {
layout: desc.layout.shared.clone(),
})
}
unsafe fn destroy_compute_pipeline(&self, pipeline: super::ComputePipeline) {
unsafe { pipeline.raw.destroy() };
}
unsafe fn destroy_compute_pipeline(&self, _pipeline: super::ComputePipeline) {}
unsafe fn create_query_set(
&self,
@ -1534,9 +1505,7 @@ impl crate::Device<super::Api> for super::Device {
Ok(super::QuerySet { raw, raw_ty })
}
unsafe fn destroy_query_set(&self, set: super::QuerySet) {
unsafe { set.raw.destroy() };
}
unsafe fn destroy_query_set(&self, _set: super::QuerySet) {}
unsafe fn create_fence(&self) -> Result<super::Fence, crate::DeviceError> {
let mut raw = d3d12::Fence::null();
@ -1551,9 +1520,7 @@ impl crate::Device<super::Api> for super::Device {
hr.into_device_result("Fence creation")?;
Ok(super::Fence { raw })
}
unsafe fn destroy_fence(&self, fence: super::Fence) {
unsafe { fence.raw.destroy() };
}
unsafe fn destroy_fence(&self, _fence: super::Fence) {}
unsafe fn get_fence_value(
&self,
fence: &super::Fence,

View File

@ -6,7 +6,6 @@ use std::{mem, sync::Arc};
impl Drop for super::Instance {
fn drop(&mut self) {
unsafe { self.factory.destroy() };
crate::auxil::dxgi::exception::unregister_exception_handler();
}
}
@ -21,7 +20,6 @@ impl crate::Instance<super::Api> for super::Instance {
Ok(pair) => match pair.into_result() {
Ok(debug_controller) => {
debug_controller.enable_layer();
unsafe { debug_controller.Release() };
}
Err(err) => {
log::warn!("Unable to enable D3D12 debug interface: {}", err);
@ -91,8 +89,8 @@ impl crate::Instance<super::Api> for super::Instance {
) -> Result<super::Surface, crate::InstanceError> {
match window_handle {
raw_window_handle::RawWindowHandle::Win32(handle) => Ok(super::Surface {
factory: self.factory,
factory_media: self.factory_media,
factory: self.factory.clone(),
factory_media: self.factory_media.clone(),
target: SurfaceTarget::WndHandle(handle.hwnd as *mut _),
supports_allow_tearing: self.supports_allow_tearing,
swap_chain: None,
@ -105,7 +103,7 @@ impl crate::Instance<super::Api> for super::Instance {
}
unsafe fn enumerate_adapters(&self) -> Vec<crate::ExposedAdapter<super::Api>> {
let adapters = auxil::dxgi::factory::enumerate_adapters(self.factory);
let adapters = auxil::dxgi::factory::enumerate_adapters(self.factory.clone());
adapters
.into_iter()

View File

@ -104,9 +104,9 @@ impl Instance {
visual: *mut dcomp::IDCompositionVisual,
) -> Surface {
Surface {
factory: self.factory,
factory_media: self.factory_media,
target: SurfaceTarget::Visual(unsafe { d3d12::WeakPtr::from_raw(visual) }),
factory: self.factory.clone(),
factory_media: self.factory_media.clone(),
target: SurfaceTarget::Visual(unsafe { d3d12::ComPtr::from_raw(visual) }),
supports_allow_tearing: self.supports_allow_tearing,
swap_chain: None,
}
@ -117,8 +117,8 @@ impl Instance {
surface_handle: winnt::HANDLE,
) -> Surface {
Surface {
factory: self.factory,
factory_media: self.factory_media,
factory: self.factory.clone(),
factory_media: self.factory_media.clone(),
target: SurfaceTarget::SurfaceHandle(surface_handle),
supports_allow_tearing: self.supports_allow_tearing,
swap_chain: None,
@ -130,7 +130,7 @@ unsafe impl Send for Instance {}
unsafe impl Sync for Instance {}
struct SwapChain {
raw: d3d12::WeakPtr<dxgi1_4::IDXGISwapChain3>,
raw: d3d12::ComPtr<dxgi1_4::IDXGISwapChain3>,
// need to associate raw image pointers with the swapchain so they can be properly released
// when the swapchain is destroyed
resources: Vec<d3d12::Resource>,
@ -143,7 +143,7 @@ struct SwapChain {
enum SurfaceTarget {
WndHandle(windef::HWND),
Visual(d3d12::WeakPtr<dcomp::IDCompositionVisual>),
Visual(d3d12::ComPtr<dcomp::IDCompositionVisual>),
SurfaceHandle(winnt::HANDLE),
}
@ -207,28 +207,12 @@ struct Idler {
event: d3d12::Event,
}
impl Idler {
unsafe fn destroy(self) {
unsafe { self.fence.destroy() };
}
}
struct CommandSignatures {
draw: d3d12::CommandSignature,
draw_indexed: d3d12::CommandSignature,
dispatch: d3d12::CommandSignature,
}
impl CommandSignatures {
unsafe fn destroy(&self) {
unsafe {
self.draw.destroy();
self.draw_indexed.destroy();
self.dispatch.destroy();
}
}
}
struct DeviceShared {
zero_buffer: d3d12::Resource,
cmd_signatures: CommandSignatures,
@ -236,17 +220,6 @@ struct DeviceShared {
heap_samplers: descriptor::GeneralHeap,
}
impl DeviceShared {
unsafe fn destroy(&self) {
unsafe {
self.zero_buffer.destroy();
self.cmd_signatures.destroy();
self.heap_views.raw.destroy();
self.heap_samplers.raw.destroy();
}
}
}
pub struct Device {
raw: d3d12::Device,
present_queue: d3d12::CommandQueue,
@ -577,18 +550,11 @@ impl CompiledShader {
fn create_native_shader(&self) -> d3d12::Shader {
match *self {
CompiledShader::Dxc(ref shader) => d3d12::Shader::from_raw(shader),
CompiledShader::Fxc(shader) => d3d12::Shader::from_blob(shader),
CompiledShader::Fxc(ref shader) => d3d12::Shader::from_blob(shader),
}
}
unsafe fn destroy(self) {
match self {
CompiledShader::Dxc(_) => {}
CompiledShader::Fxc(shader) => unsafe {
shader.destroy();
},
}
}
unsafe fn destroy(self) {}
}
pub struct RenderPipeline {
@ -610,10 +576,7 @@ unsafe impl Send for ComputePipeline {}
unsafe impl Sync for ComputePipeline {}
impl SwapChain {
unsafe fn release_resources(self) -> d3d12::WeakPtr<dxgi1_4::IDXGISwapChain3> {
for resource in self.resources {
unsafe { resource.destroy() };
}
unsafe fn release_resources(self) -> d3d12::ComPtr<dxgi1_4::IDXGISwapChain3> {
self.raw
}
@ -710,6 +673,7 @@ impl crate::Surface<Api> for Surface {
"IDXGIFactoryMedia::CreateSwapChainForCompositionSurfaceHandle"
);
self.factory_media
.clone()
.ok_or(crate::SurfaceError::Other("IDXGIFactoryMedia not found"))?
.create_swapchain_for_composition_surface_handle(
device.present_queue.as_mut_ptr() as *mut _,
@ -740,9 +704,9 @@ impl crate::Surface<Api> for Surface {
}
};
match self.target {
SurfaceTarget::WndHandle(_) | SurfaceTarget::SurfaceHandle(_) => {}
SurfaceTarget::Visual(visual) => {
match &self.target {
&SurfaceTarget::WndHandle(_) | &SurfaceTarget::SurfaceHandle(_) => {}
&SurfaceTarget::Visual(ref visual) => {
if let Err(err) =
unsafe { visual.SetContent(swap_chain1.as_unknown()) }.into_result()
{
@ -755,10 +719,7 @@ impl crate::Surface<Api> for Surface {
}
match unsafe { swap_chain1.cast::<dxgi1_4::IDXGISwapChain3>() }.into_result() {
Ok(swap_chain3) => {
unsafe { swap_chain1.destroy() };
swap_chain3
}
Ok(swap_chain3) => swap_chain3,
Err(err) => {
log::error!("Unable to cast swap chain: {}", err);
return Err(crate::SurfaceError::Other("swap chain cast to 3"));
@ -812,8 +773,7 @@ impl crate::Surface<Api> for Surface {
//TODO: this shouldn't be needed,
// but it complains that the queue is still used otherwise
let _ = device.wait_idle();
let raw = sc.release_resources();
raw.destroy();
let _raw = sc.release_resources();
}
}
}
@ -831,7 +791,7 @@ impl crate::Surface<Api> for Surface {
sc.acquired_count += 1;
let texture = Texture {
resource: sc.resources[index],
resource: sc.resources[index].clone(),
format: sc.format,
dimension: wgt::TextureDimension::D2,
size: sc.size,
@ -868,7 +828,7 @@ impl crate::Queue<Api> for Queue {
if let Some((fence, value)) = signal_fence {
self.raw
.signal(fence.raw, value)
.signal(&fence.raw, value)
.into_device_result("Signal fence")?;
}
Ok(())

View File

@ -66,9 +66,6 @@ pub(super) fn compile_fxc(
)
};
let _ = write!(full_msg, ": {}", String::from_utf8_lossy(message));
unsafe {
error.destroy();
}
}
(
Err(crate::PipelineError::Linkage(stage_bit, full_msg)),

View File

@ -16,7 +16,7 @@ use placed as allocation;
// This is the fast path using gpu_allocator to suballocate buffers and textures.
#[cfg(feature = "windows_rs")]
mod placed {
use d3d12::WeakPtr;
use d3d12::ComPtr;
use parking_lot::Mutex;
use std::ptr;
use wgt::assertions::StrictAssertUnwrapExt;
@ -64,7 +64,7 @@ mod placed {
device: &crate::dx12::Device,
desc: &crate::BufferDescriptor,
raw_desc: d3d12_ty::D3D12_RESOURCE_DESC,
resource: &mut WeakPtr<ID3D12Resource>,
resource: &mut ComPtr<ID3D12Resource>,
) -> Result<(HRESULT, Option<AllocationWrapper>), crate::DeviceError> {
let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ);
let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE);
@ -121,7 +121,7 @@ mod placed {
device: &crate::dx12::Device,
desc: &crate::TextureDescriptor,
raw_desc: d3d12_ty::D3D12_RESOURCE_DESC,
resource: &mut WeakPtr<ID3D12Resource>,
resource: &mut ComPtr<ID3D12Resource>,
) -> Result<(HRESULT, Option<AllocationWrapper>), crate::DeviceError> {
// It's a workaround for Intel Xe drivers.
if !device.private_caps.suballocation_supported {
@ -221,7 +221,7 @@ mod placed {
// 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
mod committed {
use d3d12::WeakPtr;
use d3d12::ComPtr;
use parking_lot::Mutex;
use std::ptr;
use winapi::{
@ -254,7 +254,7 @@ mod committed {
device: &crate::dx12::Device,
desc: &crate::BufferDescriptor,
raw_desc: d3d12_ty::D3D12_RESOURCE_DESC,
resource: &mut WeakPtr<ID3D12Resource>,
resource: &mut ComPtr<ID3D12Resource>,
) -> Result<(HRESULT, Option<AllocationWrapper>), crate::DeviceError> {
let is_cpu_read = desc.usage.contains(crate::BufferUses::MAP_READ);
let is_cpu_write = desc.usage.contains(crate::BufferUses::MAP_WRITE);
@ -301,7 +301,7 @@ mod committed {
device: &crate::dx12::Device,
_desc: &crate::TextureDescriptor,
raw_desc: d3d12_ty::D3D12_RESOURCE_DESC,
resource: &mut WeakPtr<ID3D12Resource>,
resource: &mut ComPtr<ID3D12Resource>,
) -> Result<(HRESULT, Option<AllocationWrapper>), crate::DeviceError> {
let heap_properties = d3d12_ty::D3D12_HEAP_PROPERTIES {
Type: d3d12_ty::D3D12_HEAP_TYPE_CUSTOM,