Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spv-out: fix acceleration structure in a function argument #5961

Merged
merged 1 commit into from
Jul 15, 2024
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 @@ -160,6 +160,7 @@ By @teoxoy in [#5901](https://github.com/gfx-rs/wgpu/pull/5901)
- Implement `WGSL`'s `unpack4xI8`,`unpack4xU8`,`pack4xI8` and `pack4xU8`. By @VlaDexa in [#5424](https://github.com/gfx-rs/wgpu/pull/5424)
- 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).
- 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)
- In spv-out, allow passing `acceleration_structure` as a function argument. By @kvark in [#5961](https://github.com/gfx-rs/wgpu/pull/5961)

```diff
let writer: naga::back::hlsl::Writer = /* ... */;
Expand Down
4 changes: 3 additions & 1 deletion naga/src/back/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,9 @@ impl crate::TypeInner {
/// Returns true if this is a handle to a type rather than the type directly.
pub const fn is_handle(&self) -> bool {
match *self {
crate::TypeInner::Image { .. } | crate::TypeInner::Sampler { .. } => true,
crate::TypeInner::Image { .. }
| crate::TypeInner::Sampler { .. }
| crate::TypeInner::AccelerationStructure { .. } => true,
_ => false,
}
}
Expand Down
25 changes: 16 additions & 9 deletions naga/tests/in/ray-query.wgsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
@group(0) @binding(0)
var acc_struct: acceleration_structure;

/*
let RAY_FLAG_NONE = 0x00u;
let RAY_FLAG_OPAQUE = 0x01u;
Expand Down Expand Up @@ -43,6 +40,18 @@ struct RayIntersection {
}
*/

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));

while (rayQueryProceed(&rq)) {}

return rayQueryGetCommittedIntersection(&rq);
}

@group(0) @binding(0)
var acc_struct: acceleration_structure;

struct Output {
visible: u32,
normal: vec3<f32>,
Expand All @@ -58,16 +67,14 @@ fn get_torus_normal(world_point: vec3<f32>, intersection: RayIntersection) -> ve
return normalize(world_point - world_point_on_guiding_line);
}



@compute @workgroup_size(1)
fn main() {
var rq: ray_query;

let pos = vec3<f32>(0.0);
let dir = vec3<f32>(0.0, 1.0, 0.0);
rayQueryInitialize(&rq, acc_struct, RayDesc(RAY_FLAG_TERMINATE_ON_FIRST_HIT, 0xFFu, 0.1, 100.0, vec3<f32>(0.0), dir));

while (rayQueryProceed(&rq)) {}
let intersection = query_loop(pos, dir, acc_struct);

let intersection = rayQueryGetCommittedIntersection(&rq);
output.visible = u32(intersection.kind == RAY_QUERY_INTERSECTION_NONE);
output.normal = get_torus_normal(dir * intersection.t, intersection);
}
59 changes: 34 additions & 25 deletions naga/tests/out/msl/ray-query.msl
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ constexpr metal::uint _map_intersection_type(const metal::raytracing::intersecti
ty==metal::raytracing::intersection_type::bounding_box ? 4 : 0;
}

struct Output {
uint visible;
char _pad1[12];
metal::float3 normal;
};
struct RayIntersection {
uint kind;
float t;
Expand All @@ -40,6 +35,34 @@ struct RayDesc {
metal::float3 origin;
metal::float3 dir;
};
struct Output {
uint visible;
char _pad1[12];
metal::float3 normal;
};

RayIntersection query_loop(
metal::float3 pos,
metal::float3 dir,
metal::raytracing::instance_acceleration_structure acs
) {
_RayQuery rq = {};
RayDesc _e8 = RayDesc {4u, 255u, 0.1, 100.0, pos, dir};
rq.intersector.assume_geometry_type(metal::raytracing::geometry_type::triangle);
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);
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);
rq.intersector.accept_any_intersection((_e8.flags & 4) != 0);
rq.intersection = rq.intersector.intersect(metal::raytracing::ray(_e8.origin, _e8.dir, _e8.tmin, _e8.tmax), acs, _e8.cull_mask); rq.ready = true;
while(true) {
bool _e9 = rq.ready;
rq.ready = false;
if (_e9) {
} else {
break;
}
}
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};
}

metal::float3 get_torus_normal(
metal::float3 world_point,
Expand All @@ -55,25 +78,11 @@ kernel void main_(
metal::raytracing::instance_acceleration_structure acc_struct [[user(fake0)]]
, device Output& output [[user(fake0)]]
) {
_RayQuery rq = {};
metal::float3 dir = metal::float3(0.0, 1.0, 0.0);
RayDesc _e12 = RayDesc {4u, 255u, 0.1, 100.0, metal::float3(0.0), dir};
rq.intersector.assume_geometry_type(metal::raytracing::geometry_type::triangle);
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);
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);
rq.intersector.accept_any_intersection((_e12.flags & 4) != 0);
rq.intersection = rq.intersector.intersect(metal::raytracing::ray(_e12.origin, _e12.dir, _e12.tmin, _e12.tmax), acc_struct, _e12.cull_mask); rq.ready = true;
while(true) {
bool _e13 = rq.ready;
rq.ready = false;
if (_e13) {
} else {
break;
}
}
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};
output.visible = static_cast<uint>(intersection_1.kind == 0u);
metal::float3 _e25 = get_torus_normal(dir * intersection_1.t, intersection_1);
output.normal = _e25;
metal::float3 pos_1 = metal::float3(0.0);
metal::float3 dir_1 = metal::float3(0.0, 1.0, 0.0);
RayIntersection _e7 = query_loop(pos_1, dir_1, acc_struct);
output.visible = static_cast<uint>(_e7.kind == 0u);
metal::float3 _e18 = get_torus_normal(dir_1 * _e7.t, _e7);
output.normal = _e18;
return;
}
Loading
Loading