Add Vulkan and DX12 backends to descriptor update

This commit is contained in:
Raph Levien 2022-06-23 15:44:42 -07:00
parent 95081971fe
commit b5b75cc42d
4 changed files with 118 additions and 17 deletions

View file

@ -21,7 +21,10 @@ use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::{BindType, BufferUsage, Error, GpuInfo, ImageLayout, MapMode, WorkgroupLimits, ImageFormat, ComputePassDescriptor}; use crate::{
BindType, BufferUsage, ComputePassDescriptor, Error, GpuInfo, ImageFormat, ImageLayout,
MapMode, WorkgroupLimits,
};
use self::{ use self::{
descriptor::{CpuHeapRefOwned, DescriptorPool, GpuHeapRefOwned}, descriptor::{CpuHeapRefOwned, DescriptorPool, GpuHeapRefOwned},
@ -322,7 +325,12 @@ impl crate::backend::Device for Dx12Device {
Ok(()) Ok(())
} }
unsafe fn create_image2d(&self, width: u32, height: u32, format: ImageFormat) -> Result<Self::Image, Error> { unsafe fn create_image2d(
&self,
width: u32,
height: u32,
format: ImageFormat,
) -> Result<Self::Image, Error> {
let format = match format { let format = match format {
ImageFormat::A8 => winapi::shared::dxgiformat::DXGI_FORMAT_R8_UNORM, ImageFormat::A8 => winapi::shared::dxgiformat::DXGI_FORMAT_R8_UNORM,
ImageFormat::Rgba8 => winapi::shared::dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM, ImageFormat::Rgba8 => winapi::shared::dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM,
@ -391,10 +399,7 @@ impl crate::backend::Device for Dx12Device {
std::ptr::copy_nonoverlapping(mapped, buf.as_mut_ptr() as *mut u8, size); std::ptr::copy_nonoverlapping(mapped, buf.as_mut_ptr() as *mut u8, size);
self.unmap_buffer(&pool.buf, 0, size as u64, MapMode::Read)?; self.unmap_buffer(&pool.buf, 0, size as u64, MapMode::Read)?;
let tsp = (self.ts_freq as f64).recip(); let tsp = (self.ts_freq as f64).recip();
let result = buf let result = buf.iter().map(|ts| *ts as f64 * tsp).collect();
.iter()
.map(|ts| *ts as f64 * tsp)
.collect();
Ok(result) Ok(result)
} }
@ -569,6 +574,28 @@ impl crate::backend::Device for Dx12Device {
DescriptorSetBuilder::default() DescriptorSetBuilder::default()
} }
unsafe fn update_buffer_descriptor(
&self,
ds: &mut Self::DescriptorSet,
index: u32,
buf: &Self::Buffer,
) {
let src_cpu_ref = buf.cpu_ref.as_ref().unwrap().handle();
ds.gpu_ref
.copy_one_descriptor(&self.device, src_cpu_ref, index);
}
unsafe fn update_image_descriptor(
&self,
ds: &mut Self::DescriptorSet,
index: u32,
image: &Self::Image,
) {
let src_cpu_ref = image.cpu_ref.as_ref().unwrap().handle();
ds.gpu_ref
.copy_one_descriptor(&self.device, src_cpu_ref, index);
}
unsafe fn create_sampler(&self, _params: crate::SamplerParams) -> Result<Self::Sampler, Error> { unsafe fn create_sampler(&self, _params: crate::SamplerParams) -> Result<Self::Sampler, Error> {
todo!() todo!()
} }

View file

@ -84,6 +84,7 @@ pub struct GpuHeapRefOwned {
heap_ref: GpuHeapRef, heap_ref: GpuHeapRef,
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_handle: D3D12_GPU_DESCRIPTOR_HANDLE, gpu_handle: D3D12_GPU_DESCRIPTOR_HANDLE,
increment_size: u32,
free_list: Weak<Mutex<DescriptorFreeList>>, free_list: Weak<Mutex<DescriptorFreeList>>,
} }
@ -137,10 +138,13 @@ impl DescriptorPool {
pub fn alloc_gpu(&mut self, device: &Device, n: u32) -> Result<GpuHeapRefOwned, Error> { pub fn alloc_gpu(&mut self, device: &Device, n: u32) -> Result<GpuHeapRefOwned, Error> {
let free_list = &self.free_list; let free_list = &self.free_list;
let heap_type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
let increment_size = unsafe { device.get_descriptor_increment_size(heap_type) };
let mk_owned = |heap_ref, cpu_handle, gpu_handle| GpuHeapRefOwned { let mk_owned = |heap_ref, cpu_handle, gpu_handle| GpuHeapRefOwned {
heap_ref, heap_ref,
cpu_handle, cpu_handle,
gpu_handle, gpu_handle,
increment_size,
free_list: Arc::downgrade(free_list), free_list: Arc::downgrade(free_list),
}; };
let mut free_list = free_list.lock().unwrap(); let mut free_list = free_list.lock().unwrap();
@ -158,7 +162,6 @@ impl DescriptorPool {
} }
unsafe { unsafe {
let size = n.max(GPU_CHUNK_SIZE).next_power_of_two(); let size = n.max(GPU_CHUNK_SIZE).next_power_of_two();
let heap_type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
let desc = D3D12_DESCRIPTOR_HEAP_DESC { let desc = D3D12_DESCRIPTOR_HEAP_DESC {
Type: heap_type, Type: heap_type,
NumDescriptors: size, NumDescriptors: size,
@ -246,6 +249,17 @@ impl GpuHeapRefOwned {
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
); );
} }
pub unsafe fn copy_one_descriptor(
&self,
device: &Device,
src: D3D12_CPU_DESCRIPTOR_HANDLE,
index: u32,
) {
let mut dst = self.cpu_handle;
dst.ptr += (index * self.increment_size) as usize;
device.copy_one_descriptor(dst, src, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
}
} }
impl Deref for CpuHeapRefOwned { impl Deref for CpuHeapRefOwned {

View file

@ -405,6 +405,16 @@ impl Device {
); );
} }
pub unsafe fn copy_one_descriptor(
&self,
dst: d3d12::D3D12_CPU_DESCRIPTOR_HANDLE,
src: d3d12::D3D12_CPU_DESCRIPTOR_HANDLE,
descriptor_heap_type: d3d12::D3D12_DESCRIPTOR_HEAP_TYPE,
) {
self.0
.CopyDescriptorsSimple(1, dst, src, descriptor_heap_type);
}
pub unsafe fn create_compute_pipeline_state( pub unsafe fn create_compute_pipeline_state(
&self, &self,
compute_pipeline_desc: &d3d12::D3D12_COMPUTE_PIPELINE_STATE_DESC, compute_pipeline_desc: &d3d12::D3D12_COMPUTE_PIPELINE_STATE_DESC,

View file

@ -7,15 +7,15 @@ use std::os::raw::c_char;
use std::sync::Arc; use std::sync::Arc;
use ash::extensions::{ext::DebugUtils, khr}; use ash::extensions::{ext::DebugUtils, khr};
use ash::{vk, Device, Entry, Instance};
use ash::vk::DebugUtilsLabelEXT; use ash::vk::DebugUtilsLabelEXT;
use ash::{vk, Device, Entry, Instance};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::backend::Device as DeviceTrait; use crate::backend::Device as DeviceTrait;
use crate::{ use crate::{
BindType, BufferUsage, Error, GpuInfo, ImageFormat, ImageLayout, MapMode, SamplerParams, SubgroupSize, BindType, BufferUsage, ComputePassDescriptor, Error, GpuInfo, ImageFormat, ImageLayout,
WorkgroupLimits, ComputePassDescriptor, MapMode, SamplerParams, SubgroupSize, WorkgroupLimits,
}; };
pub struct VkInstance { pub struct VkInstance {
@ -320,7 +320,10 @@ impl VkInstance {
let queue_index = 0; let queue_index = 0;
let queue = device.get_device_queue(qfi, queue_index); let queue = device.get_device_queue(qfi, queue_index);
let device = Arc::new(RawDevice { device, dbg_loader: self.dbg_loader.clone() }); let device = Arc::new(RawDevice {
device,
dbg_loader: self.dbg_loader.clone(),
});
let props = self.instance.get_physical_device_properties(pdevice); let props = self.instance.get_physical_device_properties(pdevice);
let timestamp_period = props.limits.timestamp_period; let timestamp_period = props.limits.timestamp_period;
@ -536,7 +539,12 @@ impl crate::backend::Device for VkDevice {
Ok(()) Ok(())
} }
unsafe fn create_image2d(&self, width: u32, height: u32, format: ImageFormat) -> Result<Self::Image, Error> { unsafe fn create_image2d(
&self,
width: u32,
height: u32,
format: ImageFormat,
) -> Result<Self::Image, Error> {
let device = &self.device.device; let device = &self.device.device;
let extent = vk::Extent3D { let extent = vk::Extent3D {
width, width,
@ -720,6 +728,49 @@ impl crate::backend::Device for VkDevice {
} }
} }
unsafe fn update_buffer_descriptor(
&self,
ds: &mut Self::DescriptorSet,
index: u32,
buf: &Self::Buffer,
) {
let device = &self.device.device;
device.update_descriptor_sets(
&[vk::WriteDescriptorSet::builder()
.dst_set(ds.descriptor_set)
.dst_binding(index)
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
.buffer_info(&[vk::DescriptorBufferInfo::builder()
.buffer(buf.buffer)
.offset(0)
.range(vk::WHOLE_SIZE)
.build()])
.build()],
&[],
);
}
unsafe fn update_image_descriptor(
&self,
ds: &mut Self::DescriptorSet,
index: u32,
image: &Self::Image,
) {
let device = &self.device.device;
device.update_descriptor_sets(
&[vk::WriteDescriptorSet::builder()
.dst_set(ds.descriptor_set)
.dst_binding(index)
.descriptor_type(vk::DescriptorType::STORAGE_IMAGE)
.image_info(&[vk::DescriptorImageInfo::builder()
.image_view(image.image_view)
.image_layout(vk::ImageLayout::GENERAL)
.build()])
.build()],
&[],
);
}
fn create_cmd_buf(&self) -> Result<CmdBuf, Error> { fn create_cmd_buf(&self) -> Result<CmdBuf, Error> {
unsafe { unsafe {
let device = &self.device.device; let device = &self.device.device;
@ -773,10 +824,7 @@ impl crate::backend::Device for VkDevice {
let flags = vk::QueryResultFlags::TYPE_64 | vk::QueryResultFlags::WAIT; let flags = vk::QueryResultFlags::TYPE_64 | vk::QueryResultFlags::WAIT;
device.get_query_pool_results(pool.pool, 0, pool.n_queries, &mut buf, flags)?; device.get_query_pool_results(pool.pool, 0, pool.n_queries, &mut buf, flags)?;
let tsp = self.timestamp_period as f64 * 1e-9; let tsp = self.timestamp_period as f64 * 1e-9;
let result = buf let result = buf.iter().map(|ts| *ts as f64 * tsp).collect();
.iter()
.map(|ts| *ts as f64 * tsp)
.collect();
Ok(result) Ok(result)
} }
@ -1129,7 +1177,9 @@ impl crate::backend::CmdBuf<VkDevice> for CmdBuf {
unsafe fn begin_debug_label(&mut self, label: &str) { unsafe fn begin_debug_label(&mut self, label: &str) {
if let Some(utils) = &self.device.dbg_loader { if let Some(utils) = &self.device.dbg_loader {
let label_cstr = CString::new(label).unwrap(); let label_cstr = CString::new(label).unwrap();
let label_ext = DebugUtilsLabelEXT::builder().label_name(&label_cstr).build(); let label_ext = DebugUtilsLabelEXT::builder()
.label_name(&label_cstr)
.build();
utils.cmd_begin_debug_utils_label(self.cmd_buf, &label_ext); utils.cmd_begin_debug_utils_label(self.cmd_buf, &label_ext);
} }
} }