Add enable extensions for ray queries and ray query vertex returns. (#8545)

This commit is contained in:
Vecvec 2025-11-19 09:56:47 +13:00 committed by GitHub
parent 853ad6c464
commit 7ba1a0e41c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 222 additions and 2 deletions

View File

@ -115,6 +115,7 @@ By @SupaMaggie70Incorporated in [#8206](https://github.com/gfx-rs/wgpu/pull/8206
#### General
- Require new enable extensions when using ray queries and position fetch (`wgpu_ray_query`, `wgpu_ray_query_vertex_return`). By @Vecvec in [#8545](https://github.com/gfx-rs/wgpu/pull/8545).
- Lower `max_blas_primitive_count` due to a bug in llvmpipe. By @Vecvec in [#8446](https://github.com/gfx-rs/wgpu/pull/8446).
- Texture now has `from_custom`. By @R-Cramer4 in [#8315](https://github.com/gfx-rs/wgpu/pull/8315).
- Using both the wgpu command encoding APIs and `CommandEncoder::as_hal_mut` on the same encoder will now result in a panic.

View File

@ -40,6 +40,7 @@ struct RayIntersection {
world_to_object: mat4x3<f32>,
}
*/
enable wgpu_ray_query;
struct Uniforms {
view_inv: mat4x4<f32>,

View File

@ -1,3 +1,5 @@
enable wgpu_ray_query;
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) tex_coords: vec2<f32>,

View File

@ -39,6 +39,8 @@ struct RayIntersection {
world_to_object: mat4x3<f32>,
}
*/
enable wgpu_ray_query;
enable wgpu_ray_query_vertex_return;
struct Uniforms {
view_inv: mat4x4<f32>,

View File

@ -1,3 +1,5 @@
enable wgpu_ray_query;
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) tex_coords: vec2<f32>,

View File

@ -1,3 +1,5 @@
enable wgpu_ray_query;
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) tex_coords: vec2<f32>,

View File

@ -1,5 +1,7 @@
// duplicate of hal's ray-traced triangle shader
enable wgpu_ray_query;
struct Uniforms {
view_inv: mat4x4<f32>,
proj_inv: mat4x4<f32>,

View File

@ -11,6 +11,8 @@ use alloc::boxed::Box;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EnableExtensions {
wgpu_mesh_shader: bool,
wgpu_ray_query: bool,
wgpu_ray_query_vertex_return: bool,
dual_source_blending: bool,
/// Whether `enable f16;` was written earlier in the shader module.
f16: bool,
@ -21,6 +23,8 @@ impl EnableExtensions {
pub(crate) const fn empty() -> Self {
Self {
wgpu_mesh_shader: false,
wgpu_ray_query: false,
wgpu_ray_query_vertex_return: false,
f16: false,
dual_source_blending: false,
clip_distances: false,
@ -31,6 +35,10 @@ impl EnableExtensions {
pub(crate) fn add(&mut self, ext: ImplementedEnableExtension) {
let field = match ext {
ImplementedEnableExtension::WgpuMeshShader => &mut self.wgpu_mesh_shader,
ImplementedEnableExtension::WgpuRayQuery => &mut self.wgpu_ray_query,
ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
&mut self.wgpu_ray_query_vertex_return
}
ImplementedEnableExtension::DualSourceBlending => &mut self.dual_source_blending,
ImplementedEnableExtension::F16 => &mut self.f16,
ImplementedEnableExtension::ClipDistances => &mut self.clip_distances,
@ -42,6 +50,10 @@ impl EnableExtensions {
pub(crate) const fn contains(&self, ext: ImplementedEnableExtension) -> bool {
match ext {
ImplementedEnableExtension::WgpuMeshShader => self.wgpu_mesh_shader,
ImplementedEnableExtension::WgpuRayQuery => self.wgpu_ray_query,
ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
self.wgpu_ray_query_vertex_return
}
ImplementedEnableExtension::DualSourceBlending => self.dual_source_blending,
ImplementedEnableExtension::F16 => self.f16,
ImplementedEnableExtension::ClipDistances => self.clip_distances,
@ -75,6 +87,8 @@ impl EnableExtension {
const CLIP_DISTANCES: &'static str = "clip_distances";
const DUAL_SOURCE_BLENDING: &'static str = "dual_source_blending";
const MESH_SHADER: &'static str = "wgpu_mesh_shader";
const RAY_QUERY: &'static str = "wgpu_ray_query";
const RAY_QUERY_VERTEX_RETURN: &'static str = "wgpu_ray_query_vertex_return";
const SUBGROUPS: &'static str = "subgroups";
const PRIMITIVE_INDEX: &'static str = "primitive_index";
@ -87,6 +101,10 @@ impl EnableExtension {
Self::Implemented(ImplementedEnableExtension::DualSourceBlending)
}
Self::MESH_SHADER => Self::Implemented(ImplementedEnableExtension::WgpuMeshShader),
Self::RAY_QUERY => Self::Implemented(ImplementedEnableExtension::WgpuRayQuery),
Self::RAY_QUERY_VERTEX_RETURN => {
Self::Implemented(ImplementedEnableExtension::WgpuRayQueryVertexReturn)
}
Self::SUBGROUPS => Self::Unimplemented(UnimplementedEnableExtension::Subgroups),
Self::PRIMITIVE_INDEX => {
Self::Unimplemented(UnimplementedEnableExtension::PrimitiveIndex)
@ -100,6 +118,10 @@ impl EnableExtension {
match self {
Self::Implemented(kind) => match kind {
ImplementedEnableExtension::WgpuMeshShader => Self::MESH_SHADER,
ImplementedEnableExtension::WgpuRayQuery => Self::RAY_QUERY,
ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
Self::RAY_QUERY_VERTEX_RETURN
}
ImplementedEnableExtension::DualSourceBlending => Self::DUAL_SOURCE_BLENDING,
ImplementedEnableExtension::F16 => Self::F16,
ImplementedEnableExtension::ClipDistances => Self::CLIP_DISTANCES,
@ -135,6 +157,10 @@ pub enum ImplementedEnableExtension {
ClipDistances,
/// Enables the `wgpu_mesh_shader` extension, native only
WgpuMeshShader,
/// Enables the `wgpu_ray_query` extension, native only.
WgpuRayQuery,
/// Enables the `wgpu_ray_query_vertex_return` extension, native only.
WgpuRayQueryVertexReturn,
}
/// A variant of [`EnableExtension::Unimplemented`].

View File

@ -1930,15 +1930,87 @@ impl Parser {
}
}
"acceleration_structure" => {
if !lexer
.enable_extensions
.contains(ImplementedEnableExtension::WgpuRayQuery)
{
return Err(Box::new(Error::EnableExtensionNotEnabled {
kind: EnableExtension::Implemented(
ImplementedEnableExtension::WgpuRayQuery,
),
span,
}));
}
let vertex_return = lexer.next_acceleration_structure_flags()?;
if !lexer
.enable_extensions
.contains(ImplementedEnableExtension::WgpuRayQueryVertexReturn)
&& vertex_return
{
return Err(Box::new(Error::EnableExtensionNotEnabled {
kind: EnableExtension::Implemented(
ImplementedEnableExtension::WgpuRayQueryVertexReturn,
),
span,
}));
}
ast::Type::AccelerationStructure { vertex_return }
}
"ray_query" => {
if !lexer
.enable_extensions
.contains(ImplementedEnableExtension::WgpuRayQuery)
{
return Err(Box::new(Error::EnableExtensionNotEnabled {
kind: EnableExtension::Implemented(
ImplementedEnableExtension::WgpuRayQuery,
),
span,
}));
}
let vertex_return = lexer.next_acceleration_structure_flags()?;
if !lexer
.enable_extensions
.contains(ImplementedEnableExtension::WgpuRayQueryVertexReturn)
&& vertex_return
{
return Err(Box::new(Error::EnableExtensionNotEnabled {
kind: EnableExtension::Implemented(
ImplementedEnableExtension::WgpuRayQueryVertexReturn,
),
span,
}));
}
ast::Type::RayQuery { vertex_return }
}
"RayDesc" => ast::Type::RayDesc,
"RayIntersection" => ast::Type::RayIntersection,
"RayDesc" => {
if !lexer
.enable_extensions
.contains(ImplementedEnableExtension::WgpuRayQuery)
{
return Err(Box::new(Error::EnableExtensionNotEnabled {
kind: EnableExtension::Implemented(
ImplementedEnableExtension::WgpuRayQuery,
),
span,
}));
}
ast::Type::RayDesc
}
"RayIntersection" => {
if !lexer
.enable_extensions
.contains(ImplementedEnableExtension::WgpuRayQuery)
{
return Err(Box::new(Error::EnableExtensionNotEnabled {
kind: EnableExtension::Implemented(
ImplementedEnableExtension::WgpuRayQuery,
),
span,
}));
}
ast::Type::RayIntersection
}
_ => return Ok(None),
}))
}

View File

@ -208,6 +208,8 @@ impl Capabilities {
// NOTE: `SHADER_FLOAT16_IN_FLOAT32` _does not_ require the `f16` extension
Self::SHADER_FLOAT16 => Some(Ext::F16),
Self::CLIP_DISTANCE => Some(Ext::ClipDistances),
Self::RAY_QUERY => Some(Ext::WgpuRayQuery),
Self::RAY_HIT_VERTEX_POSITION => Some(Ext::WgpuRayQueryVertexReturn),
_ => None,
}
}

View File

@ -1,3 +1,5 @@
enable wgpu_ray_query;
alias rq = ray_query;
@group(0) @binding(0)

View File

@ -1,3 +1,5 @@
enable wgpu_ray_query;
override o: f32;
@group(0) @binding(0)

View File

@ -40,6 +40,8 @@ struct RayIntersection {
}
*/
enable wgpu_ray_query;
fn query_loop(pos: vec3<f32>, dir: vec3<f32>, acs: acceleration_structure) -> RayIntersection {
var rq: ray_query;
rayQueryInitialize(&rq, acs, RayDesc(RAY_FLAG_TERMINATE_ON_FIRST_HIT, 0xFFu, 0.1, 100.0, pos, dir));

View File

@ -40,6 +40,8 @@ struct RayIntersection {
}
*/
enable wgpu_ray_query;
fn query_loop(pos: vec3<f32>, dir: vec3<f32>, acs: acceleration_structure) -> RayIntersection {
var rq: ray_query;
rayQueryInitialize(&rq, acs, RayDesc(RAY_FLAG_TERMINATE_ON_FIRST_HIT, 0xFFu, 0.1, 100.0, pos, dir));

View File

@ -4283,3 +4283,99 @@ fn source_with_control_char() {
",
);
}
#[test]
fn ray_query_enable_extension() {
check_extension_validation!(
Capabilities::RAY_QUERY,
r#"fn foo() {
var a: ray_query;
}
"#,
r#"error: the `wgpu_ray_query` enable extension is not enabled
wgsl:2:20
2 var a: ray_query;
^^^^^^^^^ the `wgpu_ray_query` "Enable Extension" is needed for this functionality, but it is not currently enabled.
= note: You can enable this extension by adding `enable wgpu_ray_query;` at the top of the shader, before any other items.
"#,
Err(naga::valid::ValidationError::Type {
source: naga::valid::TypeError::MissingCapability(Capabilities::RAY_QUERY),
..
})
);
check_extension_validation!(
Capabilities::RAY_QUERY,
r#"@group(0) @binding(0)
var acc_struct: acceleration_structure;
"#,
r#"error: the `wgpu_ray_query` enable extension is not enabled
wgsl:2:25
2 var acc_struct: acceleration_structure;
^^^^^^^^^^^^^^^^^^^^^^ the `wgpu_ray_query` "Enable Extension" is needed for this functionality, but it is not currently enabled.
= note: You can enable this extension by adding `enable wgpu_ray_query;` at the top of the shader, before any other items.
"#,
Err(naga::valid::ValidationError::Type {
source: naga::valid::TypeError::MissingCapability(Capabilities::RAY_QUERY),
..
})
);
}
#[test]
fn ray_query_vertex_return_enable_extension() {
check_extension_validation!(
Capabilities::RAY_HIT_VERTEX_POSITION,
r#"enable wgpu_ray_query;
fn foo() {
var a: ray_query<vertex_return>;
}
"#,
r#"error: the `wgpu_ray_query_vertex_return` enable extension is not enabled
wgsl:4:20
4 var a: ray_query<vertex_return>;
^^^^^^^^^ the `wgpu_ray_query_vertex_return` "Enable Extension" is needed for this functionality, but it is not currently enabled.
= note: You can enable this extension by adding `enable wgpu_ray_query_vertex_return;` at the top of the shader, before any other items.
"#,
Err(naga::valid::ValidationError::Type {
source: naga::valid::TypeError::MissingCapability(
Capabilities::RAY_HIT_VERTEX_POSITION
),
..
})
);
check_extension_validation!(
Capabilities::RAY_HIT_VERTEX_POSITION,
r#"enable wgpu_ray_query;
@group(0) @binding(0)
var acc_struct: acceleration_structure<vertex_return>;
"#,
r#"error: the `wgpu_ray_query_vertex_return` enable extension is not enabled
wgsl:4:25
4 var acc_struct: acceleration_structure<vertex_return>;
^^^^^^^^^^^^^^^^^^^^^^ the `wgpu_ray_query_vertex_return` "Enable Extension" is needed for this functionality, but it is not currently enabled.
= note: You can enable this extension by adding `enable wgpu_ray_query_vertex_return;` at the top of the shader, before any other items.
"#,
Err(naga::valid::ValidationError::Type {
source: naga::valid::TypeError::MissingCapability(
Capabilities::RAY_HIT_VERTEX_POSITION
),
..
})
);
}

View File

@ -1,3 +1,5 @@
enable wgpu_ray_query;
@group(0) @binding(0)
var acc_struct: acceleration_structure;

View File

@ -1,3 +1,5 @@
enable wgpu_ray_query;
struct Uniforms {
view_inv: mat4x4<f32>,
proj_inv: mat4x4<f32>,