Skip to content

Commit 9993f5c

Browse files
kvarkcwfitzgerald
andauthored
[v23] Rt constants backport (#6711)
Co-authored-by: Connor Fitzgerald <[email protected]>
1 parent cbe98e6 commit 9993f5c

File tree

13 files changed

+431
-32
lines changed

13 files changed

+431
-32
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ Bottom level categories:
4040

4141
## Unreleased
4242

43+
## 23.1.0 (2024-12-11)
44+
45+
### New Features
46+
47+
#### Naga
48+
49+
- Expose Ray Query flags as constants in WGSL. Implement candidate intersections. By @kvark in [#5429](https://github.com/gfx-rs/wgpu/pull/5429)
50+
4351
## 23.0.1 (2024-11-25)
4452

4553
This release includes patches for `wgpu`, `wgpu-core` and `wgpu-hal`. All other crates remain at [23.0.0](https://github.com/gfx-rs/wgpu/releases/tag/v23.0.0).

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/src/ray_scene/shader.wgsl

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
struct VertexOutput {
2+
@builtin(position) position: vec4<f32>,
3+
@location(0) tex_coords: vec2<f32>,
4+
};
5+
6+
@vertex
7+
fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput {
8+
var result: VertexOutput;
9+
let x = i32(vertex_index) / 2;
10+
let y = i32(vertex_index) & 1;
11+
let tc = vec2<f32>(
12+
f32(x) * 2.0,
13+
f32(y) * 2.0
14+
);
15+
result.position = vec4<f32>(
16+
tc.x * 2.0 - 1.0,
17+
1.0 - tc.y * 2.0,
18+
0.0, 1.0
19+
);
20+
result.tex_coords = tc;
21+
return result;
22+
}
23+
24+
/*
25+
The contents of the RayQuery struct are roughly as follows
26+
let RAY_FLAG_NONE = 0x00u;
27+
let RAY_FLAG_OPAQUE = 0x01u;
28+
let RAY_FLAG_NO_OPAQUE = 0x02u;
29+
let RAY_FLAG_TERMINATE_ON_FIRST_HIT = 0x04u;
30+
let RAY_FLAG_SKIP_CLOSEST_HIT_SHADER = 0x08u;
31+
let RAY_FLAG_CULL_BACK_FACING = 0x10u;
32+
let RAY_FLAG_CULL_FRONT_FACING = 0x20u;
33+
let RAY_FLAG_CULL_OPAQUE = 0x40u;
34+
let RAY_FLAG_CULL_NO_OPAQUE = 0x80u;
35+
let RAY_FLAG_SKIP_TRIANGLES = 0x100u;
36+
let RAY_FLAG_SKIP_AABBS = 0x200u;
37+
38+
let RAY_QUERY_INTERSECTION_NONE = 0u;
39+
let RAY_QUERY_INTERSECTION_TRIANGLE = 1u;
40+
let RAY_QUERY_INTERSECTION_GENERATED = 2u;
41+
let RAY_QUERY_INTERSECTION_AABB = 3u;
42+
43+
struct RayDesc {
44+
flags: u32,
45+
cull_mask: u32,
46+
t_min: f32,
47+
t_max: f32,
48+
origin: vec3<f32>,
49+
dir: vec3<f32>,
50+
}
51+
52+
struct RayIntersection {
53+
kind: u32,
54+
t: f32,
55+
instance_custom_index: u32,
56+
instance_id: u32,
57+
sbt_record_offset: u32,
58+
geometry_index: u32,
59+
primitive_index: u32,
60+
barycentrics: vec2<f32>,
61+
front_face: bool,
62+
object_to_world: mat4x3<f32>,
63+
world_to_object: mat4x3<f32>,
64+
}
65+
*/
66+
67+
struct Uniforms {
68+
view_inv: mat4x4<f32>,
69+
proj_inv: mat4x4<f32>,
70+
};
71+
72+
struct Vertex {
73+
pos: vec3<f32>,
74+
normal: vec3<f32>,
75+
uv: vec2<f32>,
76+
};
77+
78+
79+
struct Instance {
80+
first_vertex: u32,
81+
first_geometry: u32,
82+
last_geometry: u32,
83+
_pad: u32
84+
};
85+
86+
struct Material{
87+
roughness_exponent: f32,
88+
metalness: f32,
89+
specularity: f32,
90+
albedo: vec3<f32>
91+
}
92+
93+
struct Geometry {
94+
first_index: u32,
95+
material: Material,
96+
};
97+
98+
99+
@group(0) @binding(0)
100+
var<uniform> uniforms: Uniforms;
101+
102+
@group(0) @binding(1)
103+
var<storage, read> vertices: array<Vertex>;
104+
105+
@group(0) @binding(2)
106+
var<storage, read> indices: array<u32>;
107+
108+
@group(0) @binding(3)
109+
var<storage, read> geometries: array<Geometry>;
110+
111+
@group(0) @binding(4)
112+
var<storage, read> instances: array<Instance>;
113+
114+
@group(0) @binding(5)
115+
var acc_struct: acceleration_structure;
116+
117+
@fragment
118+
fn fs_main(vertex: VertexOutput) -> @location(0) vec4<f32> {
119+
120+
var color = vec4<f32>(vertex.tex_coords, 0.0, 1.0);
121+
122+
let d = vertex.tex_coords * 2.0 - 1.0;
123+
124+
let origin = (uniforms.view_inv * vec4<f32>(0.0,0.0,0.0,1.0)).xyz;
125+
let temp = uniforms.proj_inv * vec4<f32>(d.x, d.y, 1.0, 1.0);
126+
let direction = (uniforms.view_inv * vec4<f32>(normalize(temp.xyz), 0.0)).xyz;
127+
128+
var rq: ray_query;
129+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.1, 200.0, origin, direction));
130+
rayQueryProceed(&rq);
131+
132+
let intersection = rayQueryGetCommittedIntersection(&rq);
133+
if (intersection.kind != RAY_QUERY_INTERSECTION_NONE) {
134+
let instance = instances[intersection.instance_custom_index];
135+
let geometry = geometries[intersection.geometry_index + instance.first_geometry];
136+
137+
let index_offset = geometry.first_index;
138+
let vertex_offset = instance.first_vertex;
139+
140+
let first_index_index = intersection.primitive_index * 3u + index_offset;
141+
142+
let v_0 = vertices[vertex_offset+indices[first_index_index+0u]];
143+
let v_1 = vertices[vertex_offset+indices[first_index_index+1u]];
144+
let v_2 = vertices[vertex_offset+indices[first_index_index+2u]];
145+
146+
let bary = vec3<f32>(1.0 - intersection.barycentrics.x - intersection.barycentrics.y, intersection.barycentrics);
147+
148+
let pos = v_0.pos * bary.x + v_1.pos * bary.y + v_2.pos * bary.z;
149+
let normal_raw = v_0.normal * bary.x + v_1.normal * bary.y + v_2.normal * bary.z;
150+
let uv = v_0.uv * bary.x + v_1.uv * bary.y + v_2.uv * bary.z;
151+
152+
let normal = normalize(normal_raw);
153+
154+
let material = geometry.material;
155+
156+
color = vec4<f32>(material.albedo, 1.0);
157+
158+
if(intersection.instance_custom_index == 1u){
159+
color = vec4<f32>(normal, 1.0);
160+
}
161+
}
162+
163+
return color;
164+
}

naga/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "naga"
3-
version = "23.0.0"
3+
version = "23.1.0"
44
authors = ["gfx-rs developers"]
55
edition = "2021"
66
description = "Shader translation infrastructure"

naga/src/back/msl/writer.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,14 +2237,14 @@ impl<W: Write> Writer<W> {
22372237
write!(self.out, ")")?;
22382238
}
22392239
}
2240-
crate::Expression::RayQueryGetIntersection { query, committed } => {
2240+
crate::Expression::RayQueryGetIntersection {
2241+
query,
2242+
committed: _,
2243+
} => {
22412244
if context.lang_version < (2, 4) {
22422245
return Err(Error::UnsupportedRayTracing);
22432246
}
22442247

2245-
if !committed {
2246-
unimplemented!()
2247-
}
22482248
let ty = context.module.special_types.ray_intersection.unwrap();
22492249
let type_name = &self.names[&NameKey::Type(ty)];
22502250
write!(self.out, "{type_name} {{{RAY_QUERY_FUN_MAP_INTERSECTION}(")?;

naga/src/back/spv/block.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,10 +1730,7 @@ impl<'w> BlockContext<'w> {
17301730
}
17311731
crate::Expression::ArrayLength(expr) => self.write_runtime_array_length(expr, block)?,
17321732
crate::Expression::RayQueryGetIntersection { query, committed } => {
1733-
if !committed {
1734-
return Err(Error::FeatureNotImplemented("candidate intersection"));
1735-
}
1736-
self.write_ray_query_get_intersection(query, block)
1733+
self.write_ray_query_get_intersection(query, block, committed)
17371734
}
17381735
};
17391736

naga/src/back/spv/ray.rs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,23 +106,60 @@ impl<'w> BlockContext<'w> {
106106
&mut self,
107107
query: Handle<crate::Expression>,
108108
block: &mut Block,
109+
is_committed: bool,
109110
) -> spirv::Word {
110111
let query_id = self.cached[query];
111-
let intersection_id = self.writer.get_constant_scalar(crate::Literal::U32(
112-
spirv::RayQueryIntersection::RayQueryCommittedIntersectionKHR as _,
113-
));
112+
let intersection_id =
113+
self.writer
114+
.get_constant_scalar(crate::Literal::U32(if is_committed {
115+
spirv::RayQueryIntersection::RayQueryCommittedIntersectionKHR
116+
} else {
117+
spirv::RayQueryIntersection::RayQueryCandidateIntersectionKHR
118+
} as _));
114119

115120
let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
116121
NumericType::Scalar(crate::Scalar::U32),
117122
)));
118-
let kind_id = self.gen_id();
123+
let raw_kind_id = self.gen_id();
119124
block.body.push(Instruction::ray_query_get_intersection(
120125
spirv::Op::RayQueryGetIntersectionTypeKHR,
121126
flag_type_id,
122-
kind_id,
127+
raw_kind_id,
123128
query_id,
124129
intersection_id,
125130
));
131+
let kind_id = if is_committed {
132+
// Nothing to do: the IR value matches `spirv::RayQueryCommittedIntersectionType`
133+
raw_kind_id
134+
} else {
135+
// Remap from the candidate kind to IR
136+
let condition_id = self.gen_id();
137+
let committed_triangle_kind_id = self.writer.get_constant_scalar(crate::Literal::U32(
138+
spirv::RayQueryCandidateIntersectionType::RayQueryCandidateIntersectionTriangleKHR
139+
as _,
140+
));
141+
block.body.push(Instruction::binary(
142+
spirv::Op::IEqual,
143+
self.writer.get_bool_type_id(),
144+
condition_id,
145+
raw_kind_id,
146+
committed_triangle_kind_id,
147+
));
148+
let kind_id = self.gen_id();
149+
block.body.push(Instruction::select(
150+
flag_type_id,
151+
kind_id,
152+
condition_id,
153+
self.writer.get_constant_scalar(crate::Literal::U32(
154+
crate::RayQueryIntersection::Triangle as _,
155+
)),
156+
self.writer.get_constant_scalar(crate::Literal::U32(
157+
crate::RayQueryIntersection::Aabb as _,
158+
)),
159+
));
160+
kind_id
161+
};
162+
126163
let instance_custom_index_id = self.gen_id();
127164
block.body.push(Instruction::ray_query_get_intersection(
128165
spirv::Op::RayQueryGetIntersectionInstanceCustomIndexKHR,
@@ -201,6 +238,8 @@ impl<'w> BlockContext<'w> {
201238
query_id,
202239
intersection_id,
203240
));
241+
//Note: there is also `OpRayQueryGetIntersectionCandidateAABBOpaqueKHR`,
242+
// but it's not a property of an intersection.
204243

205244
let transform_type_id =
206245
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Matrix {

naga/src/front/wgsl/lower/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2563,12 +2563,22 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
25632563
args.finish()?;
25642564

25652565
let _ = ctx.module.generate_ray_intersection_type();
2566-
25672566
crate::Expression::RayQueryGetIntersection {
25682567
query,
25692568
committed: true,
25702569
}
25712570
}
2571+
"rayQueryGetCandidateIntersection" => {
2572+
let mut args = ctx.prepare_args(arguments, 1, span);
2573+
let query = self.ray_query_pointer(args.next()?, ctx)?;
2574+
args.finish()?;
2575+
2576+
let _ = ctx.module.generate_ray_intersection_type();
2577+
crate::Expression::RayQueryGetIntersection {
2578+
query,
2579+
committed: false,
2580+
}
2581+
}
25722582
"RayDesc" => {
25732583
let ty = ctx.module.generate_ray_desc_type();
25742584
let handle = self.construct(

0 commit comments

Comments
 (0)