mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
d3d12: Propagate descriptor heap and handle allocation errors (#5065)
This commit is contained in:
parent
1da093f7d6
commit
445fa6019b
@ -117,32 +117,40 @@ struct FixedSizeHeap {
|
||||
}
|
||||
|
||||
impl FixedSizeHeap {
|
||||
fn new(device: &d3d12::Device, ty: d3d12::DescriptorHeapType) -> Self {
|
||||
let (heap, _hr) = device.create_descriptor_heap(
|
||||
HEAP_SIZE_FIXED as _,
|
||||
ty,
|
||||
d3d12::DescriptorHeapFlags::empty(),
|
||||
0,
|
||||
);
|
||||
fn new(
|
||||
device: &d3d12::Device,
|
||||
ty: d3d12::DescriptorHeapType,
|
||||
) -> Result<Self, crate::DeviceError> {
|
||||
let heap = device
|
||||
.create_descriptor_heap(
|
||||
HEAP_SIZE_FIXED as _,
|
||||
ty,
|
||||
d3d12::DescriptorHeapFlags::empty(),
|
||||
0,
|
||||
)
|
||||
.into_device_result("Descriptor heap creation")?;
|
||||
|
||||
Self {
|
||||
Ok(Self {
|
||||
handle_size: device.get_descriptor_increment_size(ty) as _,
|
||||
availability: !0, // all free!
|
||||
start: heap.start_cpu_descriptor(),
|
||||
_raw: heap,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn alloc_handle(&mut self) -> d3d12::CpuDescriptor {
|
||||
fn alloc_handle(&mut self) -> Result<d3d12::CpuDescriptor, crate::DeviceError> {
|
||||
// Find first free slot.
|
||||
let slot = self.availability.trailing_zeros() as usize;
|
||||
assert!(slot < HEAP_SIZE_FIXED);
|
||||
if slot >= HEAP_SIZE_FIXED {
|
||||
log::error!("Failed to allocate a handle form a fixed size heap");
|
||||
return Err(crate::DeviceError::OutOfMemory);
|
||||
}
|
||||
// Set the slot as occupied.
|
||||
self.availability ^= 1 << slot;
|
||||
|
||||
d3d12::CpuDescriptor {
|
||||
Ok(d3d12::CpuDescriptor {
|
||||
ptr: self.start.ptr + self.handle_size * slot,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn free_handle(&mut self, handle: d3d12::CpuDescriptor) {
|
||||
@ -189,29 +197,29 @@ impl CpuPool {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn alloc_handle(&mut self) -> Handle {
|
||||
pub(super) fn alloc_handle(&mut self) -> Result<Handle, crate::DeviceError> {
|
||||
let heap_index = self
|
||||
.avaliable_heap_indices
|
||||
.iter()
|
||||
.next()
|
||||
.unwrap_or_else(|| {
|
||||
// Allocate a new heap
|
||||
let id = self.heaps.len();
|
||||
self.heaps.push(FixedSizeHeap::new(&self.device, self.ty));
|
||||
self.avaliable_heap_indices.insert(id);
|
||||
id
|
||||
});
|
||||
.unwrap_or(self.heaps.len());
|
||||
|
||||
// Allocate a new heap
|
||||
if heap_index == self.heaps.len() {
|
||||
self.heaps.push(FixedSizeHeap::new(&self.device, self.ty)?);
|
||||
self.avaliable_heap_indices.insert(heap_index);
|
||||
}
|
||||
|
||||
let heap = &mut self.heaps[heap_index];
|
||||
let handle = Handle {
|
||||
raw: heap.alloc_handle(),
|
||||
raw: heap.alloc_handle()?,
|
||||
heap_index,
|
||||
};
|
||||
if heap.is_full() {
|
||||
self.avaliable_heap_indices.remove(heap_index);
|
||||
}
|
||||
|
||||
handle
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
pub(super) fn free_handle(&mut self, handle: Handle) {
|
||||
|
@ -138,7 +138,7 @@ impl super::Device {
|
||||
};
|
||||
|
||||
let mut rtv_pool = descriptor::CpuPool::new(raw.clone(), d3d12::DescriptorHeapType::Rtv);
|
||||
let null_rtv_handle = rtv_pool.alloc_handle();
|
||||
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(
|
||||
@ -476,43 +476,47 @@ impl crate::Device<super::Api> for super::Device {
|
||||
texture.calc_subresource(desc.range.base_mip_level, desc.range.base_array_layer, 0),
|
||||
),
|
||||
handle_srv: if desc.usage.intersects(crate::TextureUses::RESOURCE) {
|
||||
let raw_desc = unsafe { view_desc.to_srv() };
|
||||
raw_desc.map(|raw_desc| {
|
||||
let handle = self.srv_uav_pool.lock().alloc_handle();
|
||||
unsafe {
|
||||
self.raw.CreateShaderResourceView(
|
||||
texture.resource.as_mut_ptr(),
|
||||
&raw_desc,
|
||||
handle.raw,
|
||||
)
|
||||
};
|
||||
handle
|
||||
})
|
||||
match unsafe { view_desc.to_srv() } {
|
||||
Some(raw_desc) => {
|
||||
let handle = self.srv_uav_pool.lock().alloc_handle()?;
|
||||
unsafe {
|
||||
self.raw.CreateShaderResourceView(
|
||||
texture.resource.as_mut_ptr(),
|
||||
&raw_desc,
|
||||
handle.raw,
|
||||
)
|
||||
};
|
||||
Some(handle)
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
},
|
||||
handle_uav: if desc.usage.intersects(
|
||||
crate::TextureUses::STORAGE_READ | crate::TextureUses::STORAGE_READ_WRITE,
|
||||
) {
|
||||
let raw_desc = unsafe { view_desc.to_uav() };
|
||||
raw_desc.map(|raw_desc| {
|
||||
let handle = self.srv_uav_pool.lock().alloc_handle();
|
||||
unsafe {
|
||||
self.raw.CreateUnorderedAccessView(
|
||||
texture.resource.as_mut_ptr(),
|
||||
ptr::null_mut(),
|
||||
&raw_desc,
|
||||
handle.raw,
|
||||
)
|
||||
};
|
||||
handle
|
||||
})
|
||||
match unsafe { view_desc.to_uav() } {
|
||||
Some(raw_desc) => {
|
||||
let handle = self.srv_uav_pool.lock().alloc_handle()?;
|
||||
unsafe {
|
||||
self.raw.CreateUnorderedAccessView(
|
||||
texture.resource.as_mut_ptr(),
|
||||
ptr::null_mut(),
|
||||
&raw_desc,
|
||||
handle.raw,
|
||||
);
|
||||
}
|
||||
Some(handle)
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
},
|
||||
handle_rtv: if desc.usage.intersects(crate::TextureUses::COLOR_TARGET) {
|
||||
let raw_desc = unsafe { view_desc.to_rtv() };
|
||||
let handle = self.rtv_pool.lock().alloc_handle();
|
||||
let handle = self.rtv_pool.lock().alloc_handle()?;
|
||||
unsafe {
|
||||
self.raw.CreateRenderTargetView(
|
||||
texture.resource.as_mut_ptr(),
|
||||
@ -529,7 +533,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
.intersects(crate::TextureUses::DEPTH_STENCIL_READ)
|
||||
{
|
||||
let raw_desc = unsafe { view_desc.to_dsv(true) };
|
||||
let handle = self.dsv_pool.lock().alloc_handle();
|
||||
let handle = self.dsv_pool.lock().alloc_handle()?;
|
||||
unsafe {
|
||||
self.raw.CreateDepthStencilView(
|
||||
texture.resource.as_mut_ptr(),
|
||||
@ -546,7 +550,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
.intersects(crate::TextureUses::DEPTH_STENCIL_WRITE)
|
||||
{
|
||||
let raw_desc = unsafe { view_desc.to_dsv(false) };
|
||||
let handle = self.dsv_pool.lock().alloc_handle();
|
||||
let handle = self.dsv_pool.lock().alloc_handle()?;
|
||||
unsafe {
|
||||
self.raw.CreateDepthStencilView(
|
||||
texture.resource.as_mut_ptr(),
|
||||
@ -588,7 +592,7 @@ impl crate::Device<super::Api> for super::Device {
|
||||
&self,
|
||||
desc: &crate::SamplerDescriptor,
|
||||
) -> Result<super::Sampler, crate::DeviceError> {
|
||||
let handle = self.sampler_pool.lock().alloc_handle();
|
||||
let handle = self.sampler_pool.lock().alloc_handle()?;
|
||||
|
||||
let reduction = match desc.compare {
|
||||
Some(_) => d3d12_ty::D3D12_FILTER_REDUCTION_TYPE_COMPARISON,
|
||||
|
Loading…
Reference in New Issue
Block a user