mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-01-08 22:08:23 -05:00
Add extra acceleration structure vertex formats. (#7580)
This commit is contained in:
@@ -51,6 +51,7 @@ Bottom level categories:
|
||||
|
||||
- Add support for astc-sliced-3d feature. By @mehmetoguzderin in [#7577](https://github.com/gfx-rs/wgpu/issues/7577)
|
||||
- Add support for rendering to slices of 3D texture views and single layered 2D-Array texture views (this requires `VK_KHR_maintenance1` which should be widely available on newer drivers). By @teoxoy in [#7596](https://github.com/gfx-rs/wgpu/pull/7596)
|
||||
- Add extra acceleration structure vertex formats. By @Vecvec in [#7580](https://github.com/gfx-rs/wgpu/pull/7580).
|
||||
|
||||
#### Naga
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::ray_tracing::AsBuildContext;
|
||||
use wgpu::util::{BufferInitDescriptor, DeviceExt};
|
||||
use wgpu::*;
|
||||
use wgpu_test::{
|
||||
fail, gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext,
|
||||
fail, fail_if, gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext,
|
||||
};
|
||||
|
||||
#[gpu_test]
|
||||
@@ -604,3 +604,106 @@ fn only_tlas_vertex_return(ctx: TestingContext) {
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpu_test]
|
||||
static EXTRA_FORMAT_BUILD: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(
|
||||
TestParameters::default()
|
||||
.test_features_limits()
|
||||
.features(
|
||||
wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE
|
||||
| wgpu::Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS,
|
||||
)
|
||||
// https://github.com/gfx-rs/wgpu/issues/6727
|
||||
.skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")),
|
||||
)
|
||||
.run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Snorm16x4, 6, false));
|
||||
|
||||
#[gpu_test]
|
||||
static MISALIGNED_BUILD: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(
|
||||
TestParameters::default()
|
||||
.test_features_limits()
|
||||
.features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)
|
||||
// https://github.com/gfx-rs/wgpu/issues/6727
|
||||
.skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")),
|
||||
)
|
||||
// Larger than the minimum size, but not aligned as required
|
||||
.run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 13, true));
|
||||
|
||||
#[gpu_test]
|
||||
static TOO_SMALL_STRIDE_BUILD: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(
|
||||
TestParameters::default()
|
||||
.test_features_limits()
|
||||
.features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)
|
||||
// https://github.com/gfx-rs/wgpu/issues/6727
|
||||
.skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")),
|
||||
)
|
||||
// Aligned as required, but smaller than minimum size
|
||||
.run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 8, true));
|
||||
|
||||
fn test_as_build_format_stride(
|
||||
ctx: TestingContext,
|
||||
format: VertexFormat,
|
||||
stride: BufferAddress,
|
||||
invalid_combination: bool,
|
||||
) {
|
||||
let vertices = ctx.device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: &vec![0; (format.min_acceleration_structure_vertex_stride() * 3) as usize],
|
||||
usage: BufferUsages::BLAS_INPUT,
|
||||
});
|
||||
|
||||
let blas_size = BlasTriangleGeometrySizeDescriptor {
|
||||
// The fourth component is ignored, and it allows us to have a smaller stride.
|
||||
vertex_format: format,
|
||||
vertex_count: 3,
|
||||
index_format: None,
|
||||
index_count: None,
|
||||
flags: wgpu::AccelerationStructureGeometryFlags::empty(),
|
||||
};
|
||||
|
||||
let blas = ctx.device.create_blas(
|
||||
&CreateBlasDescriptor {
|
||||
label: Some("BLAS"),
|
||||
flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE,
|
||||
update_mode: AccelerationStructureUpdateMode::Build,
|
||||
},
|
||||
BlasGeometrySizeDescriptors::Triangles {
|
||||
descriptors: vec![blas_size.clone()],
|
||||
},
|
||||
);
|
||||
|
||||
let mut command_encoder = ctx
|
||||
.device
|
||||
.create_command_encoder(&CommandEncoderDescriptor {
|
||||
label: Some("BLAS_1"),
|
||||
});
|
||||
fail_if(
|
||||
&ctx.device,
|
||||
invalid_combination,
|
||||
|| {
|
||||
command_encoder.build_acceleration_structures(
|
||||
&[BlasBuildEntry {
|
||||
blas: &blas,
|
||||
geometry: BlasGeometries::TriangleGeometries(vec![BlasTriangleGeometry {
|
||||
size: &blas_size,
|
||||
vertex_buffer: &vertices,
|
||||
first_vertex: 0,
|
||||
vertex_stride: stride,
|
||||
index_buffer: None,
|
||||
first_index: None,
|
||||
transform_buffer: None,
|
||||
transform_buffer_offset: None,
|
||||
}]),
|
||||
}],
|
||||
&[],
|
||||
)
|
||||
},
|
||||
None,
|
||||
);
|
||||
if !invalid_combination {
|
||||
ctx.queue.submit([command_encoder.finish()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -898,6 +898,35 @@ fn iter_blas<'a>(
|
||||
));
|
||||
}
|
||||
|
||||
if size_desc
|
||||
.vertex_format
|
||||
.min_acceleration_structure_vertex_stride()
|
||||
> mesh.vertex_stride
|
||||
{
|
||||
return Err(BuildAccelerationStructureError::VertexStrideTooSmall(
|
||||
blas.error_ident(),
|
||||
size_desc
|
||||
.vertex_format
|
||||
.min_acceleration_structure_vertex_stride(),
|
||||
mesh.vertex_stride,
|
||||
));
|
||||
}
|
||||
|
||||
if mesh.vertex_stride
|
||||
% size_desc
|
||||
.vertex_format
|
||||
.acceleration_structure_stride_alignment()
|
||||
!= 0
|
||||
{
|
||||
return Err(BuildAccelerationStructureError::VertexStrideUnaligned(
|
||||
blas.error_ident(),
|
||||
size_desc
|
||||
.vertex_format
|
||||
.acceleration_structure_stride_alignment(),
|
||||
mesh.vertex_stride,
|
||||
));
|
||||
}
|
||||
|
||||
match (size_desc.index_count, mesh.size.index_count) {
|
||||
(Some(_), None) | (None, Some(_)) => {
|
||||
return Err(
|
||||
|
||||
@@ -102,6 +102,12 @@ pub enum BuildAccelerationStructureError {
|
||||
#[error("Blas {0:?} vertex formats are different, creation format: {1:?}, provided: {2:?}")]
|
||||
DifferentBlasVertexFormats(ResourceErrorIdent, VertexFormat, VertexFormat),
|
||||
|
||||
#[error("Blas {0:?} stride was required to be at least {1} but stride given was {2}")]
|
||||
VertexStrideTooSmall(ResourceErrorIdent, u64, u64),
|
||||
|
||||
#[error("Blas {0:?} stride was required to be a multiple of {1} but stride given was {2}")]
|
||||
VertexStrideUnaligned(ResourceErrorIdent, u64, u64),
|
||||
|
||||
#[error("Blas {0:?} index count was provided at creation or building, but not the other")]
|
||||
BlasIndexCountProvidedMismatch(ResourceErrorIdent),
|
||||
|
||||
|
||||
@@ -474,7 +474,8 @@ impl super::Adapter {
|
||||
// Once ray tracing pipelines are supported they also will go here
|
||||
features.set(
|
||||
wgt::Features::EXPERIMENTAL_RAY_QUERY
|
||||
| wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE,
|
||||
| wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE
|
||||
| wgt::Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS,
|
||||
features5.RaytracingTier == Direct3D12::D3D12_RAYTRACING_TIER_1_1
|
||||
&& shader_model >= naga::back::hlsl::ShaderModel::V6_5
|
||||
&& has_features5,
|
||||
|
||||
@@ -799,7 +799,8 @@ impl PhysicalDeviceFeatures {
|
||||
features.set(F::DEPTH32FLOAT_STENCIL8, texture_d32_s8);
|
||||
|
||||
features.set(
|
||||
F::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE,
|
||||
F::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE
|
||||
| F::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS,
|
||||
caps.supports_extension(khr::deferred_host_operations::NAME)
|
||||
&& caps.supports_extension(khr::acceleration_structure::NAME)
|
||||
&& caps.supports_extension(khr::buffer_device_address::NAME),
|
||||
|
||||
@@ -1217,6 +1217,15 @@ bitflags_array! {
|
||||
///
|
||||
/// This is a native only feature.
|
||||
const EXPERIMENTAL_MESH_SHADER_MULTIVIEW = 1 << 49;
|
||||
|
||||
/// Allows usage of additional vertex formats in [BlasTriangleGeometrySizeDescriptor::vertex_format]
|
||||
///
|
||||
/// Supported platforms
|
||||
/// - Vulkan
|
||||
/// - DX12
|
||||
///
|
||||
/// [BlasTriangleGeometrySizeDescriptor::vertex_format]: super::BlasTriangleGeometrySizeDescriptor
|
||||
const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 50;
|
||||
}
|
||||
|
||||
/// Features that are not guaranteed to be supported.
|
||||
@@ -1484,6 +1493,13 @@ impl Features {
|
||||
if self.contains(Self::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) {
|
||||
formats.push(VertexFormat::Float32x3);
|
||||
}
|
||||
if self.contains(Self::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS) {
|
||||
formats.push(VertexFormat::Float32x2);
|
||||
formats.push(VertexFormat::Float16x2);
|
||||
formats.push(VertexFormat::Float16x4);
|
||||
formats.push(VertexFormat::Snorm16x2);
|
||||
formats.push(VertexFormat::Snorm16x4);
|
||||
}
|
||||
formats
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4974,6 +4974,36 @@ impl VertexFormat {
|
||||
Self::Float64x4 => 32,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the size read by an acceleration structure build of the vertex format. This is
|
||||
/// slightly different from [`Self::size`] because the alpha component of 4-component formats
|
||||
/// are not read in an acceleration structure build, allowing for a smaller stride.
|
||||
#[must_use]
|
||||
pub const fn min_acceleration_structure_vertex_stride(&self) -> u64 {
|
||||
match self {
|
||||
Self::Float16x2 | Self::Snorm16x2 => 4,
|
||||
Self::Float32x3 => 12,
|
||||
Self::Float32x2 => 8,
|
||||
// This is the minimum value from DirectX
|
||||
// > A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes
|
||||
//
|
||||
// https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#d3d12_raytracing_geometry_triangles_desc
|
||||
//
|
||||
// Vulkan does not express a minimum stride.
|
||||
Self::Float16x4 | Self::Snorm16x4 => 6,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the alignment required for `wgpu::BlasTriangleGeometry::vertex_stride`
|
||||
#[must_use]
|
||||
pub const fn acceleration_structure_stride_alignment(&self) -> u64 {
|
||||
match self {
|
||||
Self::Float16x4 | Self::Float16x2 | Self::Snorm16x4 | Self::Snorm16x2 => 2,
|
||||
Self::Float32x2 | Self::Float32x3 => 4,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
@@ -7436,7 +7466,7 @@ impl Default for ShaderRuntimeChecks {
|
||||
pub struct BlasTriangleGeometrySizeDescriptor {
|
||||
/// Format of a vertex position, must be [`VertexFormat::Float32x3`]
|
||||
/// with just [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`]
|
||||
/// but later features may add more formats.
|
||||
/// but [`Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS`] adds more.
|
||||
pub vertex_format: VertexFormat,
|
||||
/// Number of vertices.
|
||||
pub vertex_count: u32,
|
||||
|
||||
@@ -100,7 +100,8 @@ pub struct BlasTriangleGeometry<'a> {
|
||||
pub vertex_buffer: &'a Buffer,
|
||||
/// Offset into the vertex buffer as a factor of the vertex stride.
|
||||
pub first_vertex: u32,
|
||||
/// Vertex stride.
|
||||
/// Vertex stride, must be greater than [`wgpu_types::VertexFormat::min_acceleration_structure_vertex_stride`]
|
||||
/// of the format and must be a multiple of [`wgpu_types::VertexFormat::acceleration_structure_stride_alignment`].
|
||||
pub vertex_stride: wgt::BufferAddress,
|
||||
/// Index buffer (optional).
|
||||
pub index_buffer: Option<&'a Buffer>,
|
||||
|
||||
Reference in New Issue
Block a user