nir,agx: add depth=never workaround

There seems to be a hardware issue where fragment shaders with side effects get
skipped if depth testing with NEVER. Add a workaround for this case where we
discard programmatically instead.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Acked-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29179>
This commit is contained in:
Alyssa Rosenzweig
2024-04-19 22:03:16 -04:00
committed by Marge Bot
parent 9d824bd123
commit 7fb60c4c81
3 changed files with 16 additions and 1 deletions
@@ -22,7 +22,15 @@
static void
insert_z_write(nir_builder *b)
{
nir_def *z = nir_load_frag_coord_zw(b, .component = 2);
/* When forcing depth test to NEVER, force Z to NaN. This works around the
* hardware discarding depth=NEVER.
*
* TODO: Check if Apple has a better way of handling this.
*/
nir_def *bias = nir_bcsel(b, nir_ine_imm(b, nir_load_depth_never_agx(b), 0),
nir_imm_float(b, NAN), nir_imm_float(b, -0.0));
nir_def *z = nir_fadd(b, bias, nir_load_frag_coord_zw(b, .component = 2));
nir_store_output(b, z, nir_imm_int(b, 0),
.io_semantics.location = FRAG_RESULT_DEPTH,
+4
View File
@@ -1980,6 +1980,10 @@ system_value("sample_positions_agx", 1, bit_sizes=[32])
# responsible for Z/S testing after its final discard. ~0/0 boolean.
system_value("shader_part_tests_zs_agx", 1, bit_sizes=[16])
# Returns whether the API depth test is NEVER. We emulate this in shader when
# fragment side effects are used to ensure the fragment shader executes.
system_value("depth_never_agx", 1, bit_sizes=[16])
# In a fragment shader, returns the log2 of the number of samples in the
# tilebuffer. This is the unprocessed value written in the corresponding USC
# word. Used to determine whether sample mask writes have any effect when sample
@@ -192,6 +192,9 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr,
return load_sysval_root(b, 1, 16, &u->no_epilog_discard);
case nir_intrinsic_load_clip_z_coeff_agx:
return nir_f2f32(b, load_sysval_root(b, 1, 16, &u->clip_z_coeff));
case nir_intrinsic_load_depth_never_agx:
/* TODO: Do we need this workaround for anything in GL? */
return nir_imm_intN_t(b, 0, 16);
case nir_intrinsic_load_uvs_index_agx:
return load_sysval_root(
b, 1, 16, &u->uvs_index[nir_intrinsic_io_semantics(intr).location]);