mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 05:40:13 +01:00
radv/rt: Miss rays that hit the triangle's v edge
The hardware seems to do this as well. Avoids invoking hit shaders twice at shared edges. Fixes the fails in watertightness tests on emulated RT. Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24063>
This commit is contained in:
parent
a096cf784f
commit
e034ba1c44
1 changed files with 7 additions and 34 deletions
|
|
@ -253,40 +253,6 @@ intersect_ray_amd_software_tri(struct radv_device *device, nir_builder *b, nir_s
|
|||
nir_ssa_def *v = nir_fsub(b, nir_fmul(b, ax, cy), nir_fmul(b, ay, cx));
|
||||
nir_ssa_def *w = nir_fsub(b, nir_fmul(b, bx, ay), nir_fmul(b, by, ax));
|
||||
|
||||
nir_variable *u_var = nir_variable_create(b->shader, nir_var_shader_temp, glsl_float_type(), "u");
|
||||
nir_variable *v_var = nir_variable_create(b->shader, nir_var_shader_temp, glsl_float_type(), "v");
|
||||
nir_variable *w_var = nir_variable_create(b->shader, nir_var_shader_temp, glsl_float_type(), "w");
|
||||
nir_store_var(b, u_var, u, 0x1);
|
||||
nir_store_var(b, v_var, v, 0x1);
|
||||
nir_store_var(b, w_var, w, 0x1);
|
||||
|
||||
/* Fallback to testing edges with double precision...
|
||||
*
|
||||
* The Vulkan spec states it only needs single precision watertightness
|
||||
* but we fail dEQP-VK.ray_tracing_pipeline.watertightness.closedFan2.1024 with
|
||||
* failures = 1 without doing this. :( */
|
||||
nir_ssa_def *cond_retest =
|
||||
nir_ior(b, nir_ior(b, nir_feq_imm(b, u, 0.0f), nir_feq_imm(b, v, 0.0f)), nir_feq_imm(b, w, 0.0f));
|
||||
|
||||
nir_push_if(b, cond_retest);
|
||||
{
|
||||
ax = nir_f2f64(b, ax);
|
||||
ay = nir_f2f64(b, ay);
|
||||
bx = nir_f2f64(b, bx);
|
||||
by = nir_f2f64(b, by);
|
||||
cx = nir_f2f64(b, cx);
|
||||
cy = nir_f2f64(b, cy);
|
||||
|
||||
nir_store_var(b, u_var, nir_f2f32(b, nir_fsub(b, nir_fmul(b, cx, by), nir_fmul(b, cy, bx))), 0x1);
|
||||
nir_store_var(b, v_var, nir_f2f32(b, nir_fsub(b, nir_fmul(b, ax, cy), nir_fmul(b, ay, cx))), 0x1);
|
||||
nir_store_var(b, w_var, nir_f2f32(b, nir_fsub(b, nir_fmul(b, bx, ay), nir_fmul(b, by, ax))), 0x1);
|
||||
}
|
||||
nir_pop_if(b, NULL);
|
||||
|
||||
u = nir_load_var(b, u_var);
|
||||
v = nir_load_var(b, v_var);
|
||||
w = nir_load_var(b, w_var);
|
||||
|
||||
/* Perform edge tests. */
|
||||
nir_ssa_def *cond_back =
|
||||
nir_ior(b, nir_ior(b, nir_flt_imm(b, u, 0.0f), nir_flt_imm(b, v, 0.0f)), nir_flt_imm(b, w, 0.0f));
|
||||
|
|
@ -296,6 +262,13 @@ intersect_ray_amd_software_tri(struct radv_device *device, nir_builder *b, nir_s
|
|||
|
||||
nir_ssa_def *cond = nir_inot(b, nir_iand(b, cond_back, cond_front));
|
||||
|
||||
/* If the ray is exactly on the edge where v is 0, consider it a miss.
|
||||
* This seems to correspond to what the hardware is doing.
|
||||
* Also, it avoids invoking hit shaders twice on a shared edge, which is
|
||||
* discouraged by the spec.
|
||||
*/
|
||||
cond = nir_iand(b, cond, nir_fneu(b, v, nir_imm_float(b, 0.0f)));
|
||||
|
||||
nir_push_if(b, cond);
|
||||
{
|
||||
nir_ssa_def *det = nir_fadd(b, u, nir_fadd(b, v, w));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue