From 42822413cf92af13959353b485fcf6984d8da713 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 12 Mar 2023 03:16:18 -0400 Subject: [PATCH] nir: add next_stage parameter to nir_slot_is_sysval_output to return better info MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If we know the next stage, we can tell whether an output is a sysval, such as POS. For example, POS is not a sysval output if the next stage is not FS. Reviewed-by: Qiang Yu Reviewed-by: Timur Kristóf Part-of: --- src/compiler/nir/nir.c | 71 +++++++++++++++++++++----------- src/compiler/nir/nir.h | 6 ++- src/compiler/nir/nir_validate.c | 2 +- src/gallium/drivers/zink/zink_compiler.c | 2 +- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 8c0265f..761f5a0 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -3434,28 +3434,47 @@ nir_instr_xfb_write_mask(nir_intrinsic_instr *instr) * Whether an output slot is consumed by fixed-function logic. */ bool -nir_slot_is_sysval_output(gl_varying_slot slot) -{ - return slot == VARYING_SLOT_POS || - slot == VARYING_SLOT_PSIZ || - slot == VARYING_SLOT_EDGE || - slot == VARYING_SLOT_CLIP_VERTEX || - slot == VARYING_SLOT_CLIP_DIST0 || - slot == VARYING_SLOT_CLIP_DIST1 || - slot == VARYING_SLOT_CULL_DIST0 || - slot == VARYING_SLOT_CULL_DIST1 || - slot == VARYING_SLOT_LAYER || - slot == VARYING_SLOT_VIEWPORT || - slot == VARYING_SLOT_TESS_LEVEL_OUTER || - slot == VARYING_SLOT_TESS_LEVEL_INNER || - slot == VARYING_SLOT_BOUNDING_BOX0 || - slot == VARYING_SLOT_BOUNDING_BOX1 || - slot == VARYING_SLOT_VIEW_INDEX || - slot == VARYING_SLOT_VIEWPORT_MASK || - slot == VARYING_SLOT_PRIMITIVE_SHADING_RATE || - slot == VARYING_SLOT_PRIMITIVE_COUNT || - slot == VARYING_SLOT_PRIMITIVE_INDICES || - slot == VARYING_SLOT_TASK_COUNT; +nir_slot_is_sysval_output(gl_varying_slot slot, gl_shader_stage next_shader) +{ + switch (next_shader) { + case MESA_SHADER_FRAGMENT: + return slot == VARYING_SLOT_POS || + slot == VARYING_SLOT_PSIZ || + slot == VARYING_SLOT_EDGE || + slot == VARYING_SLOT_CLIP_VERTEX || + slot == VARYING_SLOT_CLIP_DIST0 || + slot == VARYING_SLOT_CLIP_DIST1 || + slot == VARYING_SLOT_CULL_DIST0 || + slot == VARYING_SLOT_CULL_DIST1 || + slot == VARYING_SLOT_LAYER || + slot == VARYING_SLOT_VIEWPORT || + slot == VARYING_SLOT_VIEW_INDEX || + slot == VARYING_SLOT_VIEWPORT_MASK || + slot == VARYING_SLOT_PRIMITIVE_SHADING_RATE || + /* NV_mesh_shader_only */ + slot == VARYING_SLOT_PRIMITIVE_COUNT || + slot == VARYING_SLOT_PRIMITIVE_INDICES; + + case MESA_SHADER_TESS_EVAL: + return slot == VARYING_SLOT_TESS_LEVEL_OUTER || + slot == VARYING_SLOT_TESS_LEVEL_INNER || + slot == VARYING_SLOT_BOUNDING_BOX0 || + slot == VARYING_SLOT_BOUNDING_BOX1; + + case MESA_SHADER_MESH: + /* NV_mesh_shader only */ + return slot == VARYING_SLOT_TASK_COUNT; + + case MESA_SHADER_NONE: + /* NONE means unknown. Check all possibilities. */ + return nir_slot_is_sysval_output(slot, MESA_SHADER_FRAGMENT) || + nir_slot_is_sysval_output(slot, MESA_SHADER_TESS_EVAL) || + nir_slot_is_sysval_output(slot, MESA_SHADER_MESH); + + default: + /* No other shaders have preceding shaders with sysval outputs. */ + return false; + } } /** @@ -3485,9 +3504,10 @@ nir_slot_is_varying(gl_varying_slot slot) } bool -nir_slot_is_sysval_output_and_varying(gl_varying_slot slot) +nir_slot_is_sysval_output_and_varying(gl_varying_slot slot, + gl_shader_stage next_shader) { - return nir_slot_is_sysval_output(slot) && + return nir_slot_is_sysval_output(slot, next_shader) && nir_slot_is_varying(slot); } @@ -3500,7 +3520,8 @@ nir_remove_varying(nir_intrinsic_instr *intr) { nir_io_semantics sem = nir_intrinsic_io_semantics(intr); - if ((!sem.no_sysval_output && nir_slot_is_sysval_output(sem.location)) || + if ((!sem.no_sysval_output && + nir_slot_is_sysval_output(sem.location, MESA_SHADER_NONE)) || nir_instr_xfb_write_mask(intr)) { /* Demote the store instruction. */ sem.no_varying = true; diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 32f201f..3784bc6 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -4779,9 +4779,11 @@ void nir_link_xfb_varyings(nir_shader *producer, nir_shader *consumer); bool nir_link_opt_varyings(nir_shader *producer, nir_shader *consumer); void nir_link_varying_precision(nir_shader *producer, nir_shader *consumer); -bool nir_slot_is_sysval_output(gl_varying_slot slot); +bool nir_slot_is_sysval_output(gl_varying_slot slot, + gl_shader_stage next_shader); bool nir_slot_is_varying(gl_varying_slot slot); -bool nir_slot_is_sysval_output_and_varying(gl_varying_slot slot); +bool nir_slot_is_sysval_output_and_varying(gl_varying_slot slot, + gl_shader_stage next_shader); bool nir_remove_varying(nir_intrinsic_instr *intr); void nir_remove_sysval_output(nir_intrinsic_instr *intr); diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 420b97c..1c68ed2 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -872,7 +872,7 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state) /* An output that has no effect shouldn't be present in the IR. */ validate_assert(state, - (nir_slot_is_sysval_output(sem.location) && + (nir_slot_is_sysval_output(sem.location, MESA_SHADER_NONE) && !sem.no_sysval_output) || (nir_slot_is_varying(sem.location) && !sem.no_varying) || nir_instr_xfb_write_mask(instr)); diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 0d35df6..769b540 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -4652,7 +4652,7 @@ fixup_io_locations(nir_shader *nir) */ unsigned slot = 0; for (unsigned i = 0; i < VARYING_SLOT_MAX; i++) { - if (nir_slot_is_sysval_output(i)) + if (nir_slot_is_sysval_output(i, MESA_SHADER_NONE)) continue; nir_variable *var = nir_find_variable_with_location(nir, mode, i); if (!var) { -- 2.7.4