mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
intel/rt: fix terminateOnFirstHit handling
If TraceRay() is called with the TerminateOnFirstHit flag, we need to
terminate the ray on the first confirmed intersection. This is handled
by the lowering of accept_ray_intersection and it's working fine for the
case of multiple instances of the intersection shader being called.
But if the shader calls reportIntersection() more than once, we were
handling them all and accepting the closest one regardless of the flag.
Check for the flag on every confirmed intersection and, if set, accept
it right there. The subsequent lowering will take care of terminating
handling the ray termination if necessary.
Fixes new test dEQP-VK.ray_tracing_pipeline.amber.flags-accept-first
Cc: mesa-stable
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30418>
(cherry picked from commit f8553f56ac)
This commit is contained in:
parent
71125139f1
commit
c8ce254e4c
2 changed files with 28 additions and 9 deletions
|
|
@ -4034,7 +4034,7 @@
|
|||
"description": "intel/rt: fix terminateOnFirstHit handling",
|
||||
"nominated": true,
|
||||
"nomination_type": 0,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -136,6 +136,19 @@ lower_any_hit_for_intersection(nir_shader *any_hit)
|
|||
return impl;
|
||||
}
|
||||
|
||||
static void
|
||||
build_accept_ray(nir_builder *b)
|
||||
{
|
||||
/* Set the "valid" bit in mem_hit */
|
||||
nir_def *ray_addr = brw_nir_rt_mem_hit_addr(b, false /* committed */);
|
||||
nir_def *flags_dw_addr = nir_iadd_imm(b, ray_addr, 12);
|
||||
nir_store_global(b, flags_dw_addr, 4,
|
||||
nir_ior(b, nir_load_global(b, flags_dw_addr, 4, 1, 32),
|
||||
nir_imm_int(b, 1 << 16)), 0x1 /* write_mask */);
|
||||
|
||||
nir_accept_ray_intersection(b);
|
||||
}
|
||||
|
||||
void
|
||||
brw_nir_lower_intersection_shader(nir_shader *intersection,
|
||||
const nir_shader *any_hit,
|
||||
|
|
@ -168,14 +181,7 @@ brw_nir_lower_intersection_shader(nir_shader *intersection,
|
|||
b->cursor = nir_after_block_before_jump(block);
|
||||
nir_push_if(b, nir_load_var(b, commit));
|
||||
{
|
||||
/* Set the "valid" bit in mem_hit */
|
||||
nir_def *ray_addr = brw_nir_rt_mem_hit_addr(b, false /* committed */);
|
||||
nir_def *flags_dw_addr = nir_iadd_imm(b, ray_addr, 12);
|
||||
nir_store_global(b, flags_dw_addr, 4,
|
||||
nir_ior(b, nir_load_global(b, flags_dw_addr, 4, 1, 32),
|
||||
nir_imm_int(b, 1 << 16)), 0x1 /* write_mask */);
|
||||
|
||||
nir_accept_ray_intersection(b);
|
||||
build_accept_ray(b);
|
||||
}
|
||||
nir_push_else(b, NULL);
|
||||
{
|
||||
|
|
@ -242,6 +248,19 @@ brw_nir_lower_intersection_shader(nir_shader *intersection,
|
|||
nir_store_global(b, t_addr, 4,
|
||||
nir_vec2(b, nir_fmin(b, hit_t, hit_in.t), hit_kind),
|
||||
0x3);
|
||||
|
||||
/* There may be multiple reportIntersection() calls in
|
||||
* the shader, so if terminateOnFirstHit was requested,
|
||||
* accept the hit now. The lowering of
|
||||
* accept_ray_intersection will handle the rest.
|
||||
*/
|
||||
nir_def *terminate = nir_test_mask(b, nir_load_ray_flags(b),
|
||||
BRW_RT_RAY_FLAG_TERMINATE_ON_FIRST_HIT);
|
||||
nir_push_if(b, terminate);
|
||||
{
|
||||
build_accept_ray(b);
|
||||
}
|
||||
nir_pop_if(b, NULL);
|
||||
}
|
||||
nir_pop_if(b, NULL);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue