mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 11:48:06 +02:00
agx: remove discard -> zs_emit lower
doesn't seem to be necessary, the Sonoma compiler uses sample_mask-based discards even with zs_emit. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27616>
This commit is contained in:
parent
0eb9b62199
commit
fd0068612f
1 changed files with 14 additions and 70 deletions
|
|
@ -52,8 +52,8 @@
|
|||
* sample_mask ~0, ~discarded
|
||||
* sample_mask ~0, ~0 <-- incorrect: depth/stencil tests run twice
|
||||
*
|
||||
* 4. If zs_emit is used anywhere in the shader, sample_mask must not be used.
|
||||
* Instead, zs_emit with depth = NaN can be emitted.
|
||||
* 4. zs_emit may be used in the shader exactly once to trigger tests.
|
||||
* sample_mask with 0 may be used to discard early.
|
||||
*
|
||||
* This pass lowers discard_agx to sample_mask instructions satisfying these
|
||||
* rules. Other passes should not generate sample_mask instructions, as there
|
||||
|
|
@ -64,48 +64,6 @@
|
|||
#define BASE_Z 1
|
||||
#define BASE_S 2
|
||||
|
||||
static bool
|
||||
lower_sample_mask_to_zs(nir_builder *b, nir_intrinsic_instr *intr,
|
||||
UNUSED void *data)
|
||||
{
|
||||
bool depth_written =
|
||||
b->shader->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH);
|
||||
bool stencil_written =
|
||||
b->shader->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL);
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
/* Existing zs_emit instructions need to be fixed up to write their own depth
|
||||
* for consistency.
|
||||
*/
|
||||
if (intr->intrinsic == nir_intrinsic_store_zs_agx && !depth_written) {
|
||||
/* Load the current depth at this pixel */
|
||||
nir_def *z = nir_load_frag_coord_zw(b, .component = 2);
|
||||
|
||||
/* Write it out from this store_zs */
|
||||
nir_intrinsic_set_base(intr, nir_intrinsic_base(intr) | BASE_Z);
|
||||
nir_src_rewrite(&intr->src[1], z);
|
||||
|
||||
/* We'll set outputs_written after the pass in case there are multiple
|
||||
* store_zs_agx instructions needing fixup.
|
||||
*/
|
||||
b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (intr->intrinsic != nir_intrinsic_discard_agx)
|
||||
return false;
|
||||
|
||||
/* Write a NaN depth value for discarded samples */
|
||||
nir_store_zs_agx(b, intr->src[0].ssa, nir_imm_float(b, NAN),
|
||||
stencil_written ? nir_imm_intN_t(b, 0, 16)
|
||||
: nir_undef(b, 1, 16) /* stencil */,
|
||||
.base = BASE_Z | (stencil_written ? BASE_S : 0));
|
||||
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_discard_to_sample_mask_0(nir_builder *b, nir_intrinsic_instr *intr,
|
||||
UNUSED void *data)
|
||||
|
|
@ -205,42 +163,28 @@ run_tests_at_start(nir_shader *shader)
|
|||
bool
|
||||
agx_nir_lower_sample_mask(nir_shader *shader, unsigned nr_samples)
|
||||
{
|
||||
bool writes_zs =
|
||||
shader->info.outputs_written &
|
||||
(BITFIELD64_BIT(FRAG_RESULT_STENCIL) | BITFIELD64_BIT(FRAG_RESULT_DEPTH));
|
||||
|
||||
if (shader->info.fs.early_fragment_tests) {
|
||||
/* run tests early, if we need testing */
|
||||
if (shader->info.fs.uses_discard ||
|
||||
(shader->info.outputs_written &
|
||||
(BITFIELD64_BIT(FRAG_RESULT_STENCIL) |
|
||||
BITFIELD64_BIT(FRAG_RESULT_DEPTH))) ||
|
||||
if (shader->info.fs.uses_discard || writes_zs ||
|
||||
shader->info.writes_memory) {
|
||||
|
||||
run_tests_at_start(shader);
|
||||
}
|
||||
} else if (shader->info.fs.uses_discard) {
|
||||
/* sample_mask can't be used with zs_emit, so lower sample_mask to zs_emit.
|
||||
* We ignore depth/stencil writes with early fragment testing though.
|
||||
/* If we have zs_emit, the tests will be triggered by zs_emit, otherwise
|
||||
* we need to trigger tests explicitly. Allow sample_mask with zs_emit.
|
||||
*/
|
||||
if (shader->info.outputs_written &
|
||||
(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
|
||||
BITFIELD64_BIT(FRAG_RESULT_STENCIL))) {
|
||||
bool progress = nir_shader_intrinsics_pass(
|
||||
shader, lower_sample_mask_to_zs,
|
||||
nir_metadata_block_index | nir_metadata_dominance, NULL);
|
||||
if (!writes_zs) {
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
|
||||
nir_builder b = nir_builder_create(impl);
|
||||
|
||||
/* The lowering requires an unconditional depth write. We mark this
|
||||
* after lowering so the lowering knows whether there was already a
|
||||
* depth write
|
||||
*/
|
||||
assert(progress && "must have lowered something,given the outputs");
|
||||
shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_DEPTH);
|
||||
|
||||
return true;
|
||||
/* run tests late */
|
||||
run_tests_after_last_discard(&b);
|
||||
}
|
||||
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
|
||||
nir_builder b = nir_builder_create(impl);
|
||||
|
||||
/* run tests late */
|
||||
run_tests_after_last_discard(&b);
|
||||
} else {
|
||||
/* regular shaders that don't use discard have nothing to lower */
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue