nir: add next_stage param to nir_slot_is_varying & nir_remove_sysval_output
The result of nir_slot_is_varying depends on what the next shader stage is, and nir_remove_sysval_output uses it. Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32855>
This commit is contained in:
@@ -254,7 +254,7 @@ bool ac_nir_optimize_outputs(nir_shader *nir, bool sprite_tex_disallowed,
|
||||
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
|
||||
|
||||
/* Only process varyings that appear as param exports. */
|
||||
if (!nir_slot_is_varying(sem.location) || sem.no_varying)
|
||||
if (!nir_slot_is_varying(sem.location, MESA_SHADER_FRAGMENT) || sem.no_varying)
|
||||
continue;
|
||||
|
||||
/* We can't optimize texture coordinates if sprite_coord_enable can override them. */
|
||||
|
||||
+14
-5
@@ -3493,11 +3493,18 @@ nir_slot_is_sysval_output(gl_varying_slot slot, gl_shader_stage next_shader)
|
||||
/**
|
||||
* Whether an input/output slot is consumed by the next shader stage,
|
||||
* or written by the previous shader stage.
|
||||
*
|
||||
* Pass MESA_SHADER_NONE if the next shader is unknown.
|
||||
*/
|
||||
bool
|
||||
nir_slot_is_varying(gl_varying_slot slot)
|
||||
nir_slot_is_varying(gl_varying_slot slot, gl_shader_stage next_shader)
|
||||
{
|
||||
bool unknown = next_shader == MESA_SHADER_NONE;
|
||||
bool exactly_before_fs = next_shader == MESA_SHADER_FRAGMENT || unknown;
|
||||
bool at_most_before_gs = next_shader <= MESA_SHADER_GEOMETRY || unknown;
|
||||
|
||||
return slot >= VARYING_SLOT_VAR0 ||
|
||||
(slot == VARYING_SLOT_POS && at_most_before_gs) ||
|
||||
slot == VARYING_SLOT_COL0 ||
|
||||
slot == VARYING_SLOT_COL1 ||
|
||||
slot == VARYING_SLOT_BFC0 ||
|
||||
@@ -3505,6 +3512,7 @@ nir_slot_is_varying(gl_varying_slot slot)
|
||||
slot == VARYING_SLOT_FOGC ||
|
||||
(slot >= VARYING_SLOT_TEX0 && slot <= VARYING_SLOT_TEX7) ||
|
||||
slot == VARYING_SLOT_PNTC ||
|
||||
(slot == VARYING_SLOT_CLIP_VERTEX && at_most_before_gs) ||
|
||||
slot == VARYING_SLOT_CLIP_DIST0 ||
|
||||
slot == VARYING_SLOT_CLIP_DIST1 ||
|
||||
slot == VARYING_SLOT_CULL_DIST0 ||
|
||||
@@ -3513,7 +3521,8 @@ nir_slot_is_varying(gl_varying_slot slot)
|
||||
slot == VARYING_SLOT_LAYER ||
|
||||
slot == VARYING_SLOT_VIEWPORT ||
|
||||
slot == VARYING_SLOT_TESS_LEVEL_OUTER ||
|
||||
slot == VARYING_SLOT_TESS_LEVEL_INNER;
|
||||
slot == VARYING_SLOT_TESS_LEVEL_INNER ||
|
||||
(slot == VARYING_SLOT_VIEW_INDEX && exactly_before_fs);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -3521,7 +3530,7 @@ nir_slot_is_sysval_output_and_varying(gl_varying_slot slot,
|
||||
gl_shader_stage next_shader)
|
||||
{
|
||||
return nir_slot_is_sysval_output(slot, next_shader) &&
|
||||
nir_slot_is_varying(slot);
|
||||
nir_slot_is_varying(slot, next_shader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3551,11 +3560,11 @@ nir_remove_varying(nir_intrinsic_instr *intr, gl_shader_stage next_shader)
|
||||
* logic. If the instruction has no other use, it's removed.
|
||||
*/
|
||||
bool
|
||||
nir_remove_sysval_output(nir_intrinsic_instr *intr)
|
||||
nir_remove_sysval_output(nir_intrinsic_instr *intr, gl_shader_stage next_shader)
|
||||
{
|
||||
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
|
||||
|
||||
if ((!sem.no_varying && nir_slot_is_varying(sem.location)) ||
|
||||
if ((!sem.no_varying && nir_slot_is_varying(sem.location, next_shader)) ||
|
||||
nir_instr_xfb_write_mask(intr)) {
|
||||
/* Demote the store instruction. */
|
||||
sem.no_sysval_output = true;
|
||||
|
||||
@@ -5696,11 +5696,11 @@ nir_opt_varyings(nir_shader *producer, nir_shader *consumer, bool spirv,
|
||||
|
||||
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_varying(gl_varying_slot slot, gl_shader_stage next_shader);
|
||||
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, gl_shader_stage next_shader);
|
||||
bool nir_remove_sysval_output(nir_intrinsic_instr *intr);
|
||||
bool nir_remove_sysval_output(nir_intrinsic_instr *intr, gl_shader_stage next_shader);
|
||||
|
||||
bool nir_lower_amul(nir_shader *shader,
|
||||
int (*type_size)(const struct glsl_type *, bool));
|
||||
|
||||
@@ -161,7 +161,8 @@ lower_store_output_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
|
||||
*/
|
||||
if ((sem.no_sysval_output ||
|
||||
!nir_slot_is_sysval_output(sem.location, MESA_SHADER_NONE)) &&
|
||||
(sem.no_varying || !nir_slot_is_varying(sem.location)) &&
|
||||
(sem.no_varying ||
|
||||
!nir_slot_is_varying(sem.location, MESA_SHADER_NONE)) &&
|
||||
!has_xfb)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ opt_clip_cull(nir_builder *b, nir_intrinsic_instr *intr, void *unused)
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_remove_sysval_output(intr);
|
||||
nir_remove_sysval_output(intr, MESA_SHADER_FRAGMENT);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -784,7 +784,8 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
|
||||
validate_assert(state,
|
||||
(nir_slot_is_sysval_output(sem.location, MESA_SHADER_NONE) &&
|
||||
!sem.no_sysval_output) ||
|
||||
(nir_slot_is_varying(sem.location) && !sem.no_varying) ||
|
||||
(nir_slot_is_varying(sem.location, MESA_SHADER_NONE) &&
|
||||
!sem.no_varying) ||
|
||||
nir_instr_xfb_write_mask(instr) ||
|
||||
/* TCS can set no_varying and no_sysval_output, meaning
|
||||
* that the output is only read by TCS and not TES.
|
||||
|
||||
@@ -1673,7 +1673,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
|
||||
assert(intr->num_components == 1); /* only scalar stores expected */
|
||||
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
|
||||
|
||||
if (nir_slot_is_varying(sem.location) &&
|
||||
if (nir_slot_is_varying(sem.location, MESA_SHADER_FRAGMENT) &&
|
||||
key->ge.opt.kill_outputs &
|
||||
(1ull << si_shader_io_get_unique_index(sem.location)))
|
||||
progress |= nir_remove_varying(intr, MESA_SHADER_FRAGMENT);
|
||||
@@ -1681,7 +1681,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
|
||||
switch (sem.location) {
|
||||
case VARYING_SLOT_PSIZ:
|
||||
if (key->ge.opt.kill_pointsize)
|
||||
progress |= nir_remove_sysval_output(intr);
|
||||
progress |= nir_remove_sysval_output(intr, MESA_SHADER_FRAGMENT);
|
||||
break;
|
||||
|
||||
case VARYING_SLOT_CLIP_VERTEX:
|
||||
@@ -1690,7 +1690,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
|
||||
*/
|
||||
if ((key->ge.opt.kill_clip_distances & SI_USER_CLIP_PLANE_MASK) ==
|
||||
SI_USER_CLIP_PLANE_MASK)
|
||||
progress |= nir_remove_sysval_output(intr);
|
||||
progress |= nir_remove_sysval_output(intr, MESA_SHADER_FRAGMENT);
|
||||
break;
|
||||
|
||||
case VARYING_SLOT_CLIP_DIST0:
|
||||
@@ -1701,7 +1701,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
|
||||
nir_intrinsic_component(intr);
|
||||
|
||||
if (key->ge.opt.kill_clip_distances & BITFIELD_BIT(index))
|
||||
progress |= nir_remove_sysval_output(intr);
|
||||
progress |= nir_remove_sysval_output(intr, MESA_SHADER_FRAGMENT);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1710,7 +1710,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
|
||||
progress |= nir_remove_varying(intr, MESA_SHADER_FRAGMENT);
|
||||
|
||||
if (key->ge.opt.kill_layer)
|
||||
progress |= nir_remove_sysval_output(intr);
|
||||
progress |= nir_remove_sysval_output(intr, MESA_SHADER_FRAGMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2033,7 +2033,7 @@ static void si_nir_assign_param_offsets(nir_shader *nir, struct si_shader *shade
|
||||
outputs_written |= BITFIELD64_BIT(sem.location);
|
||||
|
||||
/* Assign the param index if it's unassigned. */
|
||||
if (nir_slot_is_varying(sem.location) && !sem.no_varying &&
|
||||
if (nir_slot_is_varying(sem.location, MESA_SHADER_FRAGMENT) && !sem.no_varying &&
|
||||
(sem.gs_streams & 0x3) == 0 &&
|
||||
info->vs_output_param_offset[sem.location] == AC_EXP_PARAM_DEFAULT_VAL_0000) {
|
||||
/* The semantic and the base should be the same as in si_shader_info. */
|
||||
@@ -2763,7 +2763,7 @@ si_nir_generate_gs_copy_shader(struct si_screen *sscreen,
|
||||
unsigned semantic = gsinfo->output_semantic[i];
|
||||
|
||||
/* Skip if no channel writes to stream 0. */
|
||||
if (!nir_slot_is_varying(semantic) ||
|
||||
if (!nir_slot_is_varying(semantic, MESA_SHADER_FRAGMENT) ||
|
||||
(gsinfo->output_streams[i] & 0x03 &&
|
||||
gsinfo->output_streams[i] & 0x0c &&
|
||||
gsinfo->output_streams[i] & 0x30 &&
|
||||
|
||||
Reference in New Issue
Block a user