mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 04:20:08 +01:00
nir: add nir_io_semantics::no_varying, no_sysval_output, and helpers
This is for drivers that have separate store instructions for varyings, system value outputs (such as clip distances), and transform feedback. The flags tell the driver not to store the output to those locations. This will be used by radeonsi initially, and then maybe by a new linker. Reviewed-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14388>
This commit is contained in:
parent
548b2d47b2
commit
3528dcdfa1
4 changed files with 131 additions and 1 deletions
|
|
@ -3410,3 +3410,99 @@ nir_instr_xfb_write_mask(nir_intrinsic_instr *instr)
|
|||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether an input/output slot is consumed by the next shader stage,
|
||||
* or written by the previous shader stage.
|
||||
*/
|
||||
bool
|
||||
nir_slot_is_varying(gl_varying_slot slot)
|
||||
{
|
||||
return slot >= VARYING_SLOT_VAR0 ||
|
||||
slot == VARYING_SLOT_COL0 ||
|
||||
slot == VARYING_SLOT_COL1 ||
|
||||
slot == VARYING_SLOT_BFC0 ||
|
||||
slot == VARYING_SLOT_BFC1 ||
|
||||
slot == VARYING_SLOT_FOGC ||
|
||||
(slot >= VARYING_SLOT_TEX0 && slot <= VARYING_SLOT_TEX7) ||
|
||||
slot == VARYING_SLOT_CLIP_DIST0 ||
|
||||
slot == VARYING_SLOT_CLIP_DIST1 ||
|
||||
slot == VARYING_SLOT_CULL_DIST0 ||
|
||||
slot == VARYING_SLOT_CULL_DIST1 ||
|
||||
slot == VARYING_SLOT_PRIMITIVE_ID ||
|
||||
slot == VARYING_SLOT_LAYER ||
|
||||
slot == VARYING_SLOT_VIEWPORT ||
|
||||
slot == VARYING_SLOT_TESS_LEVEL_OUTER ||
|
||||
slot == VARYING_SLOT_TESS_LEVEL_INNER;
|
||||
}
|
||||
|
||||
bool
|
||||
nir_slot_is_sysval_output_and_varying(gl_varying_slot slot)
|
||||
{
|
||||
return nir_slot_is_sysval_output(slot) &&
|
||||
nir_slot_is_varying(slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* This marks the output store instruction as not feeding the next shader
|
||||
* stage. If the instruction has no other use, it's removed.
|
||||
*/
|
||||
void 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)) ||
|
||||
nir_instr_xfb_write_mask(intr)) {
|
||||
/* Demote the store instruction. */
|
||||
sem.no_varying = true;
|
||||
nir_intrinsic_set_io_semantics(intr, sem);
|
||||
} else {
|
||||
nir_instr_remove(&intr->instr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This marks the output store instruction as not feeding fixed-function
|
||||
* logic. If the instruction has no other use, it's removed.
|
||||
*/
|
||||
void nir_remove_sysval_output(nir_intrinsic_instr *intr)
|
||||
{
|
||||
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
|
||||
|
||||
if ((!sem.no_varying && nir_slot_is_varying(sem.location)) ||
|
||||
nir_instr_xfb_write_mask(intr)) {
|
||||
/* Demote the store instruction. */
|
||||
sem.no_sysval_output = true;
|
||||
nir_intrinsic_set_io_semantics(intr, sem);
|
||||
} else {
|
||||
nir_instr_remove(&intr->instr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1767,7 +1767,17 @@ typedef struct nir_io_semantics {
|
|||
unsigned per_view:1;
|
||||
unsigned high_16bits:1; /* whether accessing low or high half of the slot */
|
||||
unsigned invariant:1; /* The variable has the invariant flag set */
|
||||
unsigned _pad:5;
|
||||
/* CLIP_DISTn, LAYER, VIEWPORT, and TESS_LEVEL_* have up to 3 uses:
|
||||
* - an output consumed by the next stage
|
||||
* - a system value output affecting fixed-func hardware, e.g. the clipper
|
||||
* - a transform feedback output written to memory
|
||||
* The following fields disable the first two. Transform feedback is disabled
|
||||
* by transform feedback info.
|
||||
*/
|
||||
unsigned no_varying:1; /* whether this output isn't consumed by the next stage */
|
||||
unsigned no_sysval_output:1; /* whether this system value output has no
|
||||
effect due to current pipeline states */
|
||||
unsigned _pad:3;
|
||||
} nir_io_semantics;
|
||||
|
||||
/* Transform feedback info for 2 outputs. nir_intrinsic_store_output contains
|
||||
|
|
@ -4431,6 +4441,12 @@ 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_varying(gl_varying_slot slot);
|
||||
bool nir_slot_is_sysval_output_and_varying(gl_varying_slot slot);
|
||||
void nir_remove_varying(nir_intrinsic_instr *intr);
|
||||
void nir_remove_sysval_output(nir_intrinsic_instr *intr);
|
||||
|
||||
bool nir_lower_amul(nir_shader *shader,
|
||||
int (*type_size)(const struct glsl_type *, bool));
|
||||
|
||||
|
|
|
|||
|
|
@ -1061,6 +1061,12 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
|
|||
if (io.high_16bits)
|
||||
fprintf(fp, " high_16bits");
|
||||
|
||||
if (io.no_varying)
|
||||
fprintf(fp, " no_varying");
|
||||
|
||||
if (io.no_sysval_output)
|
||||
fprintf(fp, " no_sysval_output");
|
||||
|
||||
if (state->shader &&
|
||||
state->shader->info.stage == MESA_SHADER_GEOMETRY &&
|
||||
(instr->intrinsic == nir_intrinsic_store_output ||
|
||||
|
|
|
|||
|
|
@ -840,6 +840,18 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
|
|||
used_mask |= xfb_mask;
|
||||
}
|
||||
}
|
||||
|
||||
if (nir_intrinsic_has_io_semantics(instr) &&
|
||||
!nir_intrinsic_infos[instr->intrinsic].has_dest) {
|
||||
nir_io_semantics sem = nir_intrinsic_io_semantics(instr);
|
||||
|
||||
/* An output that has no effect shouldn't be present in the IR. */
|
||||
validate_assert(state,
|
||||
(nir_slot_is_sysval_output(sem.location) &&
|
||||
!sem.no_sysval_output) ||
|
||||
(nir_slot_is_varying(sem.location) && !sem.no_varying) ||
|
||||
nir_instr_xfb_write_mask(instr));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue