diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2017-06-14 18:35:22 +0200 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2018-06-05 16:26:24 +0200 |
commit | e5cd92413edd2adb4dd1d3d20377c734dd395f69 (patch) | |
tree | 3c7cd18d290eb5426b95c6a35d15bf3296c8073d | |
parent | 92df44881750b03f3d95ead40920caea63963b53 (diff) | |
download | mesa-e5cd92413edd2adb4dd1d3d20377c734dd395f69.tar.gz mesa-e5cd92413edd2adb4dd1d3d20377c734dd395f69.tar.xz |
etnaviv: nir: hardwire position location
The temporary input/output register 0 is reserved for position in the
fragment shader. Hardwire it to 0 and start other input/output variables
at 1. The intrinsic input load and output store base corresponds to the
temporary register number.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_nir.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_nir.c b/src/gallium/drivers/etnaviv/etnaviv_nir.c index 1ddfbb8189..3b29ea9a0e 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_nir.c +++ b/src/gallium/drivers/etnaviv/etnaviv_nir.c @@ -81,6 +81,81 @@ etna_optimize_loop(nir_shader *s) } while (progress); } +/* The temporary PS input/output register 0 is reserved for the position */ +static void +etna_hardwire_io_position(nir_shader *shader) +{ + bool fixup_needed = false; + int pos_in = -1, pos_out = -1; + int max_in = 0, max_out = 0; + + if (shader->info.stage != MESA_SHADER_FRAGMENT) + return; + + nir_foreach_variable(var, &shader->inputs) { + if (var->data.location == VARYING_SLOT_POS) { + pos_in = var->data.driver_location; + } else { + max_in = MAX2(max_in, var->data.driver_location); + if (var->data.driver_location == 0) + fixup_needed = true; + } + } + nir_foreach_variable(var, &shader->outputs) { + if (var->data.location == FRAG_RESULT_DEPTH) { + pos_out = var->data.driver_location; + } else { + max_out = MAX2(max_out, var->data.driver_location); + if (var->data.driver_location == 0) + fixup_needed = true; + } + } + + fixup_needed |= (pos_in > 0) || (pos_out > 0); + if (!fixup_needed) + return; + + if (pos_in == -1) + pos_in = max_in + 1; + if (pos_out == -1) + pos_out = max_out + 1; + + nir_foreach_variable(var, &shader->inputs) { + if (var->data.location == VARYING_SLOT_POS) + var->data.driver_location = 0; + else if (var->data.driver_location < pos_in) + var->data.driver_location++; + } + nir_foreach_variable(var, &shader->outputs) { + if (var->data.location == FRAG_RESULT_DEPTH) + var->data.driver_location = 0; + else if (var->data.driver_location < pos_out) + var->data.driver_location++; + } + + nir_foreach_function(function, shader) { + nir_foreach_block(block, function->impl) { + nir_foreach_instr(instr, block) { + if (instr->type != nir_instr_type_intrinsic) + continue; + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + unsigned pos; + if (intr->intrinsic == nir_intrinsic_load_input) + pos = pos_in; + else if (intr->intrinsic == nir_intrinsic_store_output) + pos = pos_out; + else + continue; + unsigned base = nir_intrinsic_base(intr); + if (base <= pos) + nir_intrinsic_set_base(intr, (base == pos) ? 0 : (base + 1)); + } + } + nir_metadata_preserve(function->impl, + nir_metadata_block_index | nir_metadata_dominance); + } +} + /* Move const loads, input load intrinsics, and uniform load intrinsics to the * beginning of the function implementation. * @@ -545,6 +620,7 @@ etna_optimize_nir(struct etna_shader *shader, NIR_PASS_V(s, nir_opt_global_to_local); NIR_PASS_V(s, nir_lower_regs_to_ssa); NIR_PASS_V(s, etna_move_load_intrinsics); + NIR_PASS_V(s, etna_hardwire_io_position); etna_optimize_loop(s); |