Skip to content

Commit 1b4e8ad

Browse files
kvarkteoxoy
authored andcommitted
spv-out: fix acceleration structure in a function argument
1 parent d02e294 commit 1b4e8ad

File tree

5 files changed

+193
-162
lines changed

5 files changed

+193
-162
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ By @teoxoy in [#5901](https://github.com/gfx-rs/wgpu/pull/5901)
160160
- Implement `WGSL`'s `unpack4xI8`,`unpack4xU8`,`pack4xI8` and `pack4xU8`. By @VlaDexa in [#5424](https://github.com/gfx-rs/wgpu/pull/5424)
161161
- Began work adding support for atomics to the SPIR-V frontend. Tracking issue is [here](https://github.com/gfx-rs/wgpu/issues/4489). By @schell in [#5702](https://github.com/gfx-rs/wgpu/pull/5702).
162162
- In hlsl-out, allow passing information about the fragment entry point to omit vertex outputs that are not in the fragment inputs. By @Imberflur in [#5531](https://github.com/gfx-rs/wgpu/pull/5531)
163+
- In spv-out, allow passing `acceleration_structure` as a function argument. By @kvark in [#5961](https://github.com/gfx-rs/wgpu/pull/5961)
163164

164165
```diff
165166
let writer: naga::back::hlsl::Writer = /* ... */;

naga/src/back/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,9 @@ impl crate::TypeInner {
254254
/// Returns true if this is a handle to a type rather than the type directly.
255255
pub const fn is_handle(&self) -> bool {
256256
match *self {
257-
crate::TypeInner::Image { .. } | crate::TypeInner::Sampler { .. } => true,
257+
crate::TypeInner::Image { .. }
258+
| crate::TypeInner::Sampler { .. }
259+
| crate::TypeInner::AccelerationStructure { .. } => true,
258260
_ => false,
259261
}
260262
}

naga/tests/in/ray-query.wgsl

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
@group(0) @binding(0)
2-
var acc_struct: acceleration_structure;
3-
41
/*
52
let RAY_FLAG_NONE = 0x00u;
63
let RAY_FLAG_OPAQUE = 0x01u;
@@ -43,6 +40,18 @@ struct RayIntersection {
4340
}
4441
*/
4542

43+
fn query_loop(pos: vec3<f32>, dir: vec3<f32>, acs: acceleration_structure) -> RayIntersection {
44+
var rq: ray_query;
45+
rayQueryInitialize(&rq, acs, RayDesc(RAY_FLAG_TERMINATE_ON_FIRST_HIT, 0xFFu, 0.1, 100.0, pos, dir));
46+
47+
while (rayQueryProceed(&rq)) {}
48+
49+
return rayQueryGetCommittedIntersection(&rq);
50+
}
51+
52+
@group(0) @binding(0)
53+
var acc_struct: acceleration_structure;
54+
4655
struct Output {
4756
visible: u32,
4857
normal: vec3<f32>,
@@ -58,16 +67,14 @@ fn get_torus_normal(world_point: vec3<f32>, intersection: RayIntersection) -> ve
5867
return normalize(world_point - world_point_on_guiding_line);
5968
}
6069

70+
71+
6172
@compute @workgroup_size(1)
6273
fn main() {
63-
var rq: ray_query;
64-
74+
let pos = vec3<f32>(0.0);
6575
let dir = vec3<f32>(0.0, 1.0, 0.0);
66-
rayQueryInitialize(&rq, acc_struct, RayDesc(RAY_FLAG_TERMINATE_ON_FIRST_HIT, 0xFFu, 0.1, 100.0, vec3<f32>(0.0), dir));
67-
68-
while (rayQueryProceed(&rq)) {}
76+
let intersection = query_loop(pos, dir, acc_struct);
6977

70-
let intersection = rayQueryGetCommittedIntersection(&rq);
7178
output.visible = u32(intersection.kind == RAY_QUERY_INTERSECTION_NONE);
7279
output.normal = get_torus_normal(dir * intersection.t, intersection);
7380
}

naga/tests/out/msl/ray-query.msl

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ constexpr metal::uint _map_intersection_type(const metal::raytracing::intersecti
1313
ty==metal::raytracing::intersection_type::bounding_box ? 4 : 0;
1414
}
1515

16-
struct Output {
17-
uint visible;
18-
char _pad1[12];
19-
metal::float3 normal;
20-
};
2116
struct RayIntersection {
2217
uint kind;
2318
float t;
@@ -40,6 +35,34 @@ struct RayDesc {
4035
metal::float3 origin;
4136
metal::float3 dir;
4237
};
38+
struct Output {
39+
uint visible;
40+
char _pad1[12];
41+
metal::float3 normal;
42+
};
43+
44+
RayIntersection query_loop(
45+
metal::float3 pos,
46+
metal::float3 dir,
47+
metal::raytracing::instance_acceleration_structure acs
48+
) {
49+
_RayQuery rq = {};
50+
RayDesc _e8 = RayDesc {4u, 255u, 0.1, 100.0, pos, dir};
51+
rq.intersector.assume_geometry_type(metal::raytracing::geometry_type::triangle);
52+
rq.intersector.set_opacity_cull_mode((_e8.flags & 64) != 0 ? metal::raytracing::opacity_cull_mode::opaque : (_e8.flags & 128) != 0 ? metal::raytracing::opacity_cull_mode::non_opaque : metal::raytracing::opacity_cull_mode::none);
53+
rq.intersector.force_opacity((_e8.flags & 1) != 0 ? metal::raytracing::forced_opacity::opaque : (_e8.flags & 2) != 0 ? metal::raytracing::forced_opacity::non_opaque : metal::raytracing::forced_opacity::none);
54+
rq.intersector.accept_any_intersection((_e8.flags & 4) != 0);
55+
rq.intersection = rq.intersector.intersect(metal::raytracing::ray(_e8.origin, _e8.dir, _e8.tmin, _e8.tmax), acs, _e8.cull_mask); rq.ready = true;
56+
while(true) {
57+
bool _e9 = rq.ready;
58+
rq.ready = false;
59+
if (_e9) {
60+
} else {
61+
break;
62+
}
63+
}
64+
return RayIntersection {_map_intersection_type(rq.intersection.type), rq.intersection.distance, rq.intersection.user_instance_id, rq.intersection.instance_id, {}, rq.intersection.geometry_id, rq.intersection.primitive_id, rq.intersection.triangle_barycentric_coord, rq.intersection.triangle_front_facing, {}, rq.intersection.object_to_world_transform, rq.intersection.world_to_object_transform};
65+
}
4366

4467
metal::float3 get_torus_normal(
4568
metal::float3 world_point,
@@ -55,25 +78,11 @@ kernel void main_(
5578
metal::raytracing::instance_acceleration_structure acc_struct [[user(fake0)]]
5679
, device Output& output [[user(fake0)]]
5780
) {
58-
_RayQuery rq = {};
59-
metal::float3 dir = metal::float3(0.0, 1.0, 0.0);
60-
RayDesc _e12 = RayDesc {4u, 255u, 0.1, 100.0, metal::float3(0.0), dir};
61-
rq.intersector.assume_geometry_type(metal::raytracing::geometry_type::triangle);
62-
rq.intersector.set_opacity_cull_mode((_e12.flags & 64) != 0 ? metal::raytracing::opacity_cull_mode::opaque : (_e12.flags & 128) != 0 ? metal::raytracing::opacity_cull_mode::non_opaque : metal::raytracing::opacity_cull_mode::none);
63-
rq.intersector.force_opacity((_e12.flags & 1) != 0 ? metal::raytracing::forced_opacity::opaque : (_e12.flags & 2) != 0 ? metal::raytracing::forced_opacity::non_opaque : metal::raytracing::forced_opacity::none);
64-
rq.intersector.accept_any_intersection((_e12.flags & 4) != 0);
65-
rq.intersection = rq.intersector.intersect(metal::raytracing::ray(_e12.origin, _e12.dir, _e12.tmin, _e12.tmax), acc_struct, _e12.cull_mask); rq.ready = true;
66-
while(true) {
67-
bool _e13 = rq.ready;
68-
rq.ready = false;
69-
if (_e13) {
70-
} else {
71-
break;
72-
}
73-
}
74-
RayIntersection intersection_1 = RayIntersection {_map_intersection_type(rq.intersection.type), rq.intersection.distance, rq.intersection.user_instance_id, rq.intersection.instance_id, {}, rq.intersection.geometry_id, rq.intersection.primitive_id, rq.intersection.triangle_barycentric_coord, rq.intersection.triangle_front_facing, {}, rq.intersection.object_to_world_transform, rq.intersection.world_to_object_transform};
75-
output.visible = static_cast<uint>(intersection_1.kind == 0u);
76-
metal::float3 _e25 = get_torus_normal(dir * intersection_1.t, intersection_1);
77-
output.normal = _e25;
81+
metal::float3 pos_1 = metal::float3(0.0);
82+
metal::float3 dir_1 = metal::float3(0.0, 1.0, 0.0);
83+
RayIntersection _e7 = query_loop(pos_1, dir_1, acc_struct);
84+
output.visible = static_cast<uint>(_e7.kind == 0u);
85+
metal::float3 _e18 = get_torus_normal(dir_1 * _e7.t, _e7);
86+
output.normal = _e18;
7887
return;
7988
}

0 commit comments

Comments
 (0)