More future proof, simpler, and works with early I/O lowering.
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19456>
# src[] = { value }
store("raw_output_pan", [], [])
-store("combined_output_pan", [1, 1, 1, 4], [BASE, COMPONENT, SRC_TYPE, DEST_TYPE])
-load("raw_output_pan", [1], [BASE], [CAN_ELIMINATE, CAN_REORDER])
+store("combined_output_pan", [1, 1, 1, 4], [IO_SEMANTICS, COMPONENT, SRC_TYPE, DEST_TYPE])
+load("raw_output_pan", [1], [IO_SEMANTICS], [CAN_ELIMINATE, CAN_REORDER])
# Loads the sampler paramaters <min_lod, max_lod, lod_bias>
# src[] = { sampler_index }
bool emit_blend = writeout & (PAN_WRITEOUT_C);
bool emit_zs = writeout & (PAN_WRITEOUT_Z | PAN_WRITEOUT_S);
- const nir_variable *var =
- nir_find_variable_with_driver_location(b->shader->nir,
- nir_var_shader_out, nir_intrinsic_base(instr));
-
- unsigned loc = var ? var->data.location : 0;
-
+ unsigned loc = nir_intrinsic_io_semantics(instr).location;
bi_index src0 = bi_src_index(&instr->src[0]);
/* By ISA convention, the coverage mask is stored in R60. The store
/* Explicit copy since BLEND inputs are precoloured to R0-R3,
* TODO: maybe schedule around this or implement in RA as a
* spill */
- bool has_mrt = false;
-
- nir_foreach_shader_out_variable(var, b->shader->nir)
- has_mrt |= (var->data.location > FRAG_RESULT_DATA0);
+ bool has_mrt = (b->shader->nir->info.outputs_written >> FRAG_RESULT_DATA1);
if (has_mrt) {
bi_index srcs[4] = { color, color, color, color };
/* Get the render target */
if (!b->shader->inputs->is_blend) {
- const nir_variable *var =
- nir_find_variable_with_driver_location(b->shader->nir,
- nir_var_shader_out, nir_intrinsic_base(instr));
- unsigned loc = var->data.location;
+ nir_io_semantics sem = nir_intrinsic_io_semantics(instr);
+ unsigned loc = sem.location;
assert(loc >= FRAG_RESULT_DATA0);
rt = (loc - FRAG_RESULT_DATA0);
}
if (ctx->inputs->is_blend)
return MIDGARD_COLOR_RT0 + ctx->inputs->blend.rt;
- const nir_variable *var;
- var = nir_find_variable_with_driver_location(ctx->nir, nir_var_shader_out, nir_intrinsic_base(instr));
- assert(var);
-
- unsigned loc = var->data.location;
+ unsigned loc = nir_intrinsic_io_semantics(instr).location;
if (loc >= FRAG_RESULT_DATA0)
return loc - FRAG_RESULT_DATA0;
}
if (writeout & PAN_WRITEOUT_C) {
- const nir_variable *var =
- nir_find_variable_with_driver_location(ctx->nir, nir_var_shader_out,
- nir_intrinsic_base(instr));
-
- assert(var != NULL);
- assert(var->data.location >= FRAG_RESULT_DATA0);
+ nir_io_semantics sem = nir_intrinsic_io_semantics(instr);
- rt = MIDGARD_COLOR_RT0 + var->data.location -
- FRAG_RESULT_DATA0;
+ rt = MIDGARD_COLOR_RT0 +
+ (sem.location - FRAG_RESULT_DATA0);
} else {
rt = MIDGARD_ZS_RT;
}
nir_intrinsic_instr *intr,
const struct util_format_description *desc,
bool reorder_comps,
- unsigned base, int sample)
+ int sample)
{
+ nir_io_semantics sem = {
+ .location = nir_intrinsic_get_var(intr, 0)->data.location,
+ };
+
nir_ssa_def *packed =
nir_load_raw_output_pan(b, 4, 32, pan_sample_id(b, sample),
- .base = base);
+ .io_semantics = sem);
/* Convert the raw value */
nir_ssa_def *unpacked = pan_unpack(b, desc, packed);
if (var->data.location < FRAG_RESULT_DATA0)
continue;
- unsigned base = var->data.driver_location;
unsigned rt = var->data.location - FRAG_RESULT_DATA0;
if (rt_fmts[rt] == PIPE_FORMAT_NONE)
pan_lower_fb_store(shader, &b, intr, desc, reorder_comps);
} else {
b.cursor = nir_after_instr(instr);
- pan_lower_fb_load(shader, &b, intr, desc, reorder_comps, base, sample);
+ pan_lower_fb_load(shader, &b, intr, desc, reorder_comps, sample);
}
nir_instr_remove(instr);
intr->num_components = rt0_store ? rt0_store->src[0].ssa->num_components : 4;
if (rt0_store)
- nir_intrinsic_set_base(intr, nir_intrinsic_base(rt0_store));
+ nir_intrinsic_set_io_semantics(intr, nir_intrinsic_io_semantics(rt0_store));
nir_intrinsic_set_src_type(intr, pan_nir_rt_store_type(rt0_store));
nir_intrinsic_set_dest_type(intr, pan_nir_rt_store_type(stores[2]));
nir_intrinsic_set_component(intr, writeout);
bool
pan_nir_lower_zs_store(nir_shader *nir)
{
- if (nir->info.stage != MESA_SHADER_FRAGMENT)
- return false;
-
- nir_variable *vars[3] = { NULL };
-
- nir_foreach_shader_out_variable(var, nir) {
- if (var->data.location == FRAG_RESULT_DEPTH)
- vars[0] = var;
- else if (var->data.location == FRAG_RESULT_STENCIL)
- vars[1] = var;
- else if (var->data.index)
- vars[2] = var;
- }
+ bool progress = false;
- if (!vars[0] && !vars[1] && !vars[2])
+ if (nir->info.stage != MESA_SHADER_FRAGMENT)
return false;
- bool progress = false;
-
nir_foreach_function(function, nir) {
if (!function->impl) continue;
nir_intrinsic_instr *stores[3] = { NULL };
+ unsigned writeout = 0;
nir_foreach_block(block, function->impl) {
nir_foreach_instr_safe(instr, block) {
if (intr->intrinsic != nir_intrinsic_store_output)
continue;
- for (unsigned i = 0; i < ARRAY_SIZE(vars); ++i) {
- if (vars[i] && nir_intrinsic_base(intr) == vars[i]->data.driver_location) {
- assert(!stores[i]);
- stores[i] = intr;
- }
+ nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
+ if (sem.location == FRAG_RESULT_DEPTH) {
+ stores[0] = intr;
+ writeout |= PAN_WRITEOUT_Z;
+ } else if (sem.location == FRAG_RESULT_STENCIL) {
+ stores[1] = intr;
+ writeout |= PAN_WRITEOUT_S;
+ } else if (sem.dual_source_blend_index) {
+ stores[2] = intr;
+ writeout |= PAN_WRITEOUT_2;
}
}
}
- if (!stores[0] && !stores[1] && !stores[2]) continue;
+ if (!writeout) continue;
nir_block *common_block = NULL;
common_block = block;
}
- unsigned writeout = 0;
- if (stores[0])
- writeout |= PAN_WRITEOUT_Z;
- if (stores[1])
- writeout |= PAN_WRITEOUT_S;
- if (stores[2])
- writeout |= PAN_WRITEOUT_2;
-
bool replaced = false;
nir_foreach_block(block, function->impl) {
if (intr->intrinsic != nir_intrinsic_store_output)
continue;
- const nir_variable *var = nir_find_variable_with_driver_location(nir, nir_var_shader_out, nir_intrinsic_base(intr));
- assert(var);
+ nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
- if (var->data.location < FRAG_RESULT_DATA0)
+ if (sem.location < FRAG_RESULT_DATA0)
continue;
- if (var->data.index)
+ if (sem.dual_source_blend_index)
continue;
assert(nir_src_is_const(intr->src[1]) && "no indirect outputs");