diff --git a/src/asahi/compiler/agx_nir_lower_frag_sidefx.c b/src/asahi/compiler/agx_nir_lower_frag_sidefx.c index f1a3923ca86..a7b17660608 100644 --- a/src/asahi/compiler/agx_nir_lower_frag_sidefx.c +++ b/src/asahi/compiler/agx_nir_lower_frag_sidefx.c @@ -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, diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index afedab3e979..74c5f21c533 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -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 diff --git a/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c b/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c index d6376ead752..b17d3dfb5d0 100644 --- a/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c +++ b/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c @@ -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]);