From 40fb95d51a8af5d8f1ff2b70b385703632837e53 Mon Sep 17 00:00:00 2001 From: Kevin Chuang Date: Wed, 12 Feb 2025 19:42:04 -0800 Subject: [PATCH] intel/compiler: Use 24bits for hit_kind on Xe3+ For Xe3+, the upper 8 bits of the second dword of a potential hit is used to store hitGroupIndex0, which is stuffed by the HW. This hitGroupIndex0 will later be used by the HW again to reconstruct the whole hitGroupIndex when driver issues a TRACE_RAY_COMMIT. We were corrupting this hitGroupIndex0 at the driver by setting the whole dword to hit_kind, which will cause the HW to read a wrong hitGroupIndex and therefore invoke a wrong closest hit shader. The behavior can be seen in dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.gpu.boxes.\* and dEQP-VK.ray_tracing_pipeline.pipeline_library.configurations.\* This commit changes the driver to only use lower 24bits to store the hit_kind, and leave the upper 8bits as it. Signed-off-by: Kevin Chuang Reviewed-by: Sagar Ghuge Reviewed-by: Lionel Landwerlin Part-of: --- .../brw_nir_lower_intersection_shader.c | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/intel/compiler/brw_nir_lower_intersection_shader.c b/src/intel/compiler/brw_nir_lower_intersection_shader.c index 2d3624b0450..76d0c5110c6 100644 --- a/src/intel/compiler/brw_nir_lower_intersection_shader.c +++ b/src/intel/compiler/brw_nir_lower_intersection_shader.c @@ -241,9 +241,37 @@ brw_nir_lower_intersection_shader(nir_shader *intersection, brw_nir_rt_mem_ray_addr(b, brw_nir_rt_stack_addr(b), BRW_RT_BVH_LEVEL_WORLD); nir_store_global(b, nir_iadd_imm(b, ray_addr, 16 + 12), 4, hit_t, 0x1); - nir_store_global(b, t_addr, 4, - nir_vec2(b, nir_fmin(b, hit_t, hit_in.t), hit_kind), - 0x3); + if (devinfo->ver >= 30) { + /* For Xe3+, the most significant 8 bits of the second + * DW in the potential hit are used to store + * hitGroupIndex0, which will later be used by HW to + * reconstruct the whole hitGroupIndex while issuing a + * TRACE_RAY_COMMIT. So we can't corrupt the data + * stored here. We can still use the lower 24bits to + * store aabb_hit_kind tho. + */ + nir_def *potential_hit_dword_1 = + brw_nir_rt_load(b, nir_iadd_imm(b, t_addr, 4), 4, 1, 32); + nir_def *hit_group_index_0 = + nir_iand_imm(b, potential_hit_dword_1, 0xff000000); + + /* Chop off hit_kind and make it only 24bits. This + * prevents the hit_group_index_0 to be corrupted, but + * also implies the application shouldn't pass a + * gl_HitKindEXT that uses more than 24bits. + */ + nir_def *hit_kind_24b = nir_iand_imm(b, hit_kind, 0xffffff); + nir_store_global(b, t_addr, 4, + nir_vec2(b, + nir_fmin(b, hit_t, hit_in.t), + nir_ior(b, hit_group_index_0, hit_kind_24b)), + 0x3); + + } else { + 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,