Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/backend/dx12/src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,10 @@ pub fn map_descriptor_range(bind: &DescriptorSetLayoutBinding, register_space: u
D3D12_DESCRIPTOR_RANGE {
RangeType: match bind.ty {
pso::DescriptorType::Sampler => D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
pso::DescriptorType::SampledImage => D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
pso::DescriptorType::SampledImage |
pso::DescriptorType::UniformTexelBuffer => D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
pso::DescriptorType::StorageBuffer |
pso::DescriptorType::StorageTexelBuffer |
pso::DescriptorType::StorageImage => D3D12_DESCRIPTOR_RANGE_TYPE_UAV,
pso::DescriptorType::UniformBuffer => D3D12_DESCRIPTOR_RANGE_TYPE_CBV,
pso::DescriptorType::CombinedImageSampler => if sampler {
Expand Down
102 changes: 96 additions & 6 deletions src/backend/dx12/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use hal::queue::{RawCommandQueue, QueueFamilyId};
use hal::range::RangeArg;

use {
conv, free_list, native as n, root_constants, window as w,
conv, format as fmt, free_list, native as n, root_constants, window as w,
Backend as B, Device, MemoryGroup, QUEUE_FAMILIES, MAX_VERTEX_BUFFERS, NUM_HEAP_PROPERTIES,
};
use pool::RawCommandPool;
Expand Down Expand Up @@ -216,6 +216,18 @@ impl Device {
.map_err(gen_unexpected_error)?;
}

for storage_buffer in &shader_resources.storage_buffers {
let set = ast.get_decoration(storage_buffer.id, spirv::Decoration::DescriptorSet).map_err(gen_query_error)?;
ast.set_decoration(storage_buffer.id, spirv::Decoration::DescriptorSet, space_offset + set)
.map_err(gen_unexpected_error)?;
}

for image in &shader_resources.storage_images {
let set = ast.get_decoration(image.id, spirv::Decoration::DescriptorSet).map_err(gen_query_error)?;
ast.set_decoration(image.id, spirv::Decoration::DescriptorSet, space_offset + set)
.map_err(gen_unexpected_error)?;
}

for sampler in &shader_resources.separate_samplers {
let set = ast.get_decoration(sampler.id, spirv::Decoration::DescriptorSet).map_err(gen_query_error)?;
ast.set_decoration(sampler.id, spirv::Decoration::DescriptorSet, space_offset + set)
Expand Down Expand Up @@ -1698,11 +1710,80 @@ impl d::Device<B> for Device {

fn create_buffer_view<R: RangeArg<u64>>(
&self,
_buffer: &n::Buffer,
_format: Option<format::Format>,
_range: R,
buffer: &n::Buffer,
format: Option<format::Format>,
range: R,
) -> Result<n::BufferView, buffer::ViewError> {
unimplemented!()
let buffer_features = {
let idx = format.map(|fmt| fmt as usize).unwrap_or(0);
fmt::query_properties()[idx].buffer_features
};
let (format, format_desc) = match format.and_then(conv::map_format) {
Some(fmt) => (fmt, format.unwrap().surface_desc()),
None => return Err(buffer::ViewError::Unsupported),
};

let start = *range.start().unwrap_or(&0);
let end = *range.end().unwrap_or(&(buffer.size_in_bytes as _));

let bytes_per_texel = (format_desc.bits / 8) as u64;
// Check if it adheres to the texel buffer offset limit
assert_eq!(start % bytes_per_texel, 0);
let first_element = start / bytes_per_texel;
let num_elements = (end - start) / bytes_per_texel; // rounds down to next smaller size

let handle_srv = if buffer_features.contains(format::BufferFeature::UNIFORM_TEXEL) {
let mut desc = d3d12::D3D12_SHADER_RESOURCE_VIEW_DESC {
Format: format,
ViewDimension: d3d12::D3D12_SRV_DIMENSION_BUFFER,
Shader4ComponentMapping: 0x1688, // TODO: verify
u: unsafe { mem::zeroed() },
};

*unsafe{ desc.u.Buffer_mut() } = d3d12::D3D12_BUFFER_SRV {
FirstElement: first_element,
NumElements: num_elements as _,
StructureByteStride: bytes_per_texel as _,
Flags: d3d12::D3D12_BUFFER_SRV_FLAG_NONE,
};

let handle = self.srv_pool.lock().unwrap().alloc_handles(1).cpu;
unsafe {
self.raw.clone().CreateShaderResourceView(buffer.resource, &desc, handle);
}
handle
} else {
d3d12::D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 }
};

let handle_uav = if buffer_features.intersects(format::BufferFeature::STORAGE_TEXEL | format::BufferFeature::STORAGE_TEXEL_ATOMIC) {
let mut desc = d3d12::D3D12_UNORDERED_ACCESS_VIEW_DESC {
Format: format,
ViewDimension: d3d12::D3D12_UAV_DIMENSION_BUFFER,
u: unsafe { mem::zeroed() },
};

*unsafe{ desc.u.Buffer_mut() } = d3d12::D3D12_BUFFER_UAV {
FirstElement: first_element,
NumElements: num_elements as _,
StructureByteStride: bytes_per_texel as _,
Flags: d3d12::D3D12_BUFFER_UAV_FLAG_NONE,
CounterOffsetInBytes: 0,
};

let handle = self.uav_pool.lock().unwrap().alloc_handles(1).cpu;
unsafe {
self.raw.clone().CreateUnorderedAccessView(buffer.resource, ptr::null_mut(), &desc, handle);
}
handle
} else {
d3d12::D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 }
};

return Ok(n::BufferView {
handle_srv,
handle_uav,
});
}

fn create_image(
Expand Down Expand Up @@ -2193,7 +2274,16 @@ impl d::Device<B> for Device {
dst_samplers.push(bind_info.sampler_range.as_ref().unwrap().at(offset));
num_samplers.push(1);
}
pso::Descriptor::TexelBuffer(_) => unimplemented!()
pso::Descriptor::UniformTexelBuffer(buffer_view) => {
src_views.push(buffer_view.handle_srv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that the SRV here and UAV below can be NULL, can we at least error!() on it?

dst_views.push(bind_info.view_range.as_ref().unwrap().at(offset));
num_views.push(1);
}
pso::Descriptor::StorageTexelBuffer(buffer_view) => {
src_views.push(buffer_view.handle_uav);
dst_views.push(bind_info.view_range.as_ref().unwrap().at(offset));
num_views.push(1);
}
}
offset += 1;
}
Expand Down
15 changes: 12 additions & 3 deletions src/backend/dx12/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,18 @@ pub struct Buffer {
unsafe impl Send for Buffer { }
unsafe impl Sync for Buffer { }

#[derive(Debug, Hash, PartialEq, Eq)]
pub struct BufferView;

#[derive(Copy, Clone, Derivative)]
#[derivative(Debug)]
pub struct BufferView {
// Descriptor handle for uniform texel buffers.
#[derivative(Debug="ignore")]
pub(crate) handle_srv: d3d12::D3D12_CPU_DESCRIPTOR_HANDLE,
// Descriptor handle for storage texel buffers.
#[derivative(Debug="ignore")]
pub(crate) handle_uav: d3d12::D3D12_CPU_DESCRIPTOR_HANDLE,
}
unsafe impl Send for BufferView { }
unsafe impl Sync for BufferView { }

#[derive(Clone, Derivative)]
#[derivative(Debug)]
Expand Down
3 changes: 2 additions & 1 deletion src/backend/metal/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,8 @@ impl hal::Device<Backend> for Device {
(&pso::Descriptor::CombinedImageSampler(image, layout, sampler), &mut n::DescriptorSetBinding::Combined(ref mut vec)) => {
vec[array_offset] = Some((image.0.clone(), layout, sampler.0.clone()));
}
(&pso::Descriptor::TexelBuffer(view), &mut n::DescriptorSetBinding::Image(ref mut vec)) => {
(&pso::Descriptor::UniformTexelBuffer(view), &mut n::DescriptorSetBinding::Image(ref mut vec)) |
(&pso::Descriptor::StorageTexelBuffer(view), &mut n::DescriptorSetBinding::Image(ref mut vec)) => {
vec[array_offset] = Some((view.raw.clone(), image::Layout::General));
}
(&pso::Descriptor::Buffer(buffer, ref range), &mut n::DescriptorSetBinding::Buffer(ref mut vec)) => {
Expand Down
3 changes: 2 additions & 1 deletion src/backend/vulkan/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,8 @@ impl d::Device<B> for Device {
},
});
}
pso::Descriptor::TexelBuffer(view) => {
pso::Descriptor::UniformTexelBuffer(view) |
pso::Descriptor::StorageTexelBuffer(view) => {
texel_buffer_views.push(view.raw);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/hal/src/pso/descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ pub enum Descriptor<'a, B: Backend> {
Image(&'a B::ImageView, Layout),
CombinedImageSampler(&'a B::ImageView, Layout, &'a B::Sampler),
Buffer(&'a B::Buffer, Range<Option<Offset>>),
TexelBuffer(&'a B::BufferView),
UniformTexelBuffer(&'a B::BufferView),
StorageTexelBuffer(&'a B::BufferView),
}


Expand Down