Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
105 changes: 104 additions & 1 deletion tests/tests/wgpu-gpu/ray_tracing/as_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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()]);
}
}
29 changes: 29 additions & 0 deletions wgpu-core/src/command/ray_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
6 changes: 6 additions & 0 deletions wgpu-core/src/ray_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),

Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
16 changes: 16 additions & 0 deletions wgpu-types/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
}
Expand Down
32 changes: 31 additions & 1 deletion wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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! {
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion wgpu/src/api/blas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down
Loading