Commit 29b128fc authored by Joshua Ashton's avatar Joshua Ashton 🐸
Browse files

radv: Use sign bit xorf stuff for RT watertightness

Re-read over the paper, and decided to try implementing this part exactly like how they did and made things "exact".

Didn't seem to help with the weird CTS failures. I wonder if I need to do something else to preserve sign bits.

https://jcgt.org/published/0002/01/05/paper.pdf
parent 341278f0
Pipeline #449216 waiting for manual action with stages
......@@ -1540,12 +1540,22 @@ nir_sort_hit_pair(nir_builder *b, nir_variable *var_distances, nir_variable *var
nir_pop_if(b, NULL);
}
static nir_ssa_def *
nir_xorf(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y_sign)
{
nir_ssa_def *x_sign = nir_iand(b, x, nir_imm_int(b, 1u << 31));
nir_ssa_def *sign_result = nir_ixor(b, y_sign, x_sign);
return nir_ior(b, nir_iand(b, x, nir_imm_int(b, ~(1u << 31))), sign_result);
}
static nir_ssa_def *
intersect_ray_amd_software_box(struct radv_device *device,
nir_builder *b, nir_ssa_def *bvh_node,
nir_ssa_def *ray_tmax, nir_ssa_def *origin,
nir_ssa_def *dir, nir_ssa_def *inv_dir)
{
bool exact_store = b->exact;
b->exact = true;
const struct glsl_type *vec4_type = glsl_vector_type(GLSL_TYPE_FLOAT, 4);
const struct glsl_type *uvec4_type = glsl_vector_type(GLSL_TYPE_UINT, 4);
......@@ -1630,6 +1640,8 @@ intersect_ray_amd_software_box(struct radv_device *device,
nir_sort_hit_pair(b, distances, child_indices, 1, 3);
nir_sort_hit_pair(b, distances, child_indices, 1, 2);
b->exact = exact_store;
return nir_load_var(b, child_indices);
}
......@@ -1639,6 +1651,8 @@ intersect_ray_amd_software_tri(struct radv_device *device,
nir_ssa_def *ray_tmax, nir_ssa_def *origin,
nir_ssa_def *dir, nir_ssa_def *inv_dir)
{
bool exact_store = b->exact;
b->exact = true;
const struct glsl_type *vec4_type = glsl_vector_type(GLSL_TYPE_FLOAT, 4);
nir_ssa_def *node_addr = build_node_to_addr(device, b, bvh_node);
......@@ -1721,6 +1735,7 @@ intersect_ray_amd_software_tri(struct radv_device *device,
nir_store_var(b, v_var, v, 0x1);
nir_store_var(b, w_var, w, 0x1);
#if 1
/* Fallback to testing edges with double precision...
*
* The Vulkan spec states it only needs single precision watertightness
......@@ -1742,6 +1757,7 @@ intersect_ray_amd_software_tri(struct radv_device *device,
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);
#endif
u = nir_load_var(b, u_var);
v = nir_load_var(b, v_var);
......@@ -1763,29 +1779,41 @@ intersect_ray_amd_software_tri(struct radv_device *device,
nir_push_if(b, cond);
{
nir_ssa_def *det = nir_fadd(b, u, nir_fadd(b, v, w));
nir_ssa_def *det_not_zero = nir_inot(b, nir_feq(b, det, nir_imm_float(b, 0.0f)));
nir_push_if(b, det_not_zero);
{
nir_ssa_def *az = nir_fmul(b, sz, nir_vector_extract(b, v_a, kz));
nir_ssa_def *bz = nir_fmul(b, sz, nir_vector_extract(b, v_b, kz));
nir_ssa_def *cz = nir_fmul(b, sz, nir_vector_extract(b, v_c, kz));
nir_ssa_def *az = nir_fmul(b, sz, nir_vector_extract(b, v_a, kz));
nir_ssa_def *bz = nir_fmul(b, sz, nir_vector_extract(b, v_b, kz));
nir_ssa_def *cz = nir_fmul(b, sz, nir_vector_extract(b, v_c, kz));
nir_ssa_def *t = nir_fadd(b, nir_fadd(b, nir_fmul(b, u, az), nir_fmul(b, v, bz)), nir_fmul(b, w, cz));
nir_ssa_def *t = nir_fadd(b, nir_fadd(b, nir_fmul(b, u, az), nir_fmul(b, v, bz)), nir_fmul(b, w, cz));
nir_ssa_def *t_signed = nir_fmul(b, nir_fsign(b, det), t);
nir_ssa_def *det_sign = nir_iand(b, det, nir_imm_int(b, 1u << 31));
nir_ssa_def *xorf_t = nir_xorf(b, t, det_sign);
nir_ssa_def *det_cond_front = nir_inot(b, nir_flt(b, t_signed, nir_imm_float(b, 0.0f)));
nir_ssa_def *det_cond_front = nir_flt(b, xorf_t, nir_imm_float(b, 0.0f));
/*nir_ssa_def *det_cond_back = nir_flt(b,
nir_fmul(b, nir_imm_float(b, INFINITY), nir_xorf(b, det, det_sign)),
xorf_t);*/
nir_ssa_def *det_cond_back = nir_flt(b, nir_fmul(b, nir_imm_float(b, INFINITY), nir_fabs(b, det)), xorf_t);
nir_ssa_def *det_cond = nir_inot(b, nir_ior(b, det_cond_front, det_cond_back));
nir_push_if(b, det_cond_front);
{
nir_ssa_def *indices[4] = {
t, det,
v, w
};
nir_store_var(b, result, nir_vec(b, indices, 4), 0xf);
nir_push_if(b, det_cond);
{
nir_ssa_def *indices[4] = {
t, det,
v, w
};
nir_store_var(b, result, nir_vec(b, indices, 4), 0xf);
}
nir_pop_if(b, NULL);
}
nir_pop_if(b, NULL);
}
nir_pop_if(b, NULL);
b->exact = exact_store;
return nir_load_var(b, result);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment