[Mesa-dev] [PATCH] nir: add tess patch support to nir_remove_unused_varyings()
Nicolai Hähnle
nhaehnle at gmail.com
Thu Nov 2 15:38:01 UTC 2017
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
On 25.10.2017 10:06, Timothy Arceri wrote:
> Shader-db results BDW:
>
> total instructions in shared programs: 13276247 -> 13275395 (-0.01%)
> instructions in affected programs: 29407 -> 28555 (-2.90%)
> helped: 71
> HURT: 0
>
> total cycles in shared programs: 539866300 -> 539861882 (-0.00%)
> cycles in affected programs: 127518 -> 123100 (-3.46%)
> helped: 71
> HURT: 1
>
> These are all Shadow of Mordor shaders.
> ---
> src/compiler/nir/nir_linking_helpers.c | 61 +++++++++++++++++++++++-----------
> 1 file changed, 42 insertions(+), 19 deletions(-)
>
> diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c
> index 54ba1c85e58..4d709c1b3c5 100644
> --- a/src/compiler/nir/nir_linking_helpers.c
> +++ b/src/compiler/nir/nir_linking_helpers.c
> @@ -37,10 +37,12 @@
> static uint64_t
> get_variable_io_mask(nir_variable *var, gl_shader_stage stage)
> {
> - /* TODO: add support for tess patches */
> - if (var->data.patch || var->data.location < 0)
> + if (var->data.location < 0)
> return 0;
>
> + unsigned location = var->data.patch ?
> + var->data.location - VARYING_SLOT_PATCH0 : var->data.location;
> +
> assert(var->data.mode == nir_var_shader_in ||
> var->data.mode == nir_var_shader_out ||
> var->data.mode == nir_var_system_value);
> @@ -53,11 +55,11 @@ get_variable_io_mask(nir_variable *var, gl_shader_stage stage)
> }
>
> unsigned slots = glsl_count_attribute_slots(type, false);
> - return ((1ull << slots) - 1) << var->data.location;
> + return ((1ull << slots) - 1) << location;
> }
>
> static void
> -tcs_add_output_reads(nir_shader *shader, uint64_t *read)
> +tcs_add_output_reads(nir_shader *shader, uint64_t *read, uint64_t *patches_read)
> {
> nir_foreach_function(function, shader) {
> if (function->impl) {
> @@ -73,9 +75,15 @@ tcs_add_output_reads(nir_shader *shader, uint64_t *read)
> nir_var_shader_out) {
>
> nir_variable *var = intrin_instr->variables[0]->var;
> - read[var->data.location_frac] |=
> - get_variable_io_mask(intrin_instr->variables[0]->var,
> - shader->info.stage);
> + if (var->data.patch) {
> + patches_read[var->data.location_frac] |=
> + get_variable_io_mask(intrin_instr->variables[0]->var,
> + shader->info.stage);
> + } else {
> + read[var->data.location_frac] |=
> + get_variable_io_mask(intrin_instr->variables[0]->var,
> + shader->info.stage);
> + }
> }
> }
> }
> @@ -85,14 +93,17 @@ tcs_add_output_reads(nir_shader *shader, uint64_t *read)
>
> static bool
> remove_unused_io_vars(nir_shader *shader, struct exec_list *var_list,
> - uint64_t *used_by_other_stage)
> + uint64_t *used_by_other_stage,
> + uint64_t *used_by_other_stage_patches)
> {
> bool progress = false;
> + uint64_t *used;
>
> nir_foreach_variable_safe(var, var_list) {
> - /* TODO: add patch support */
> if (var->data.patch)
> - continue;
> + used = used_by_other_stage_patches;
> + else
> + used = used_by_other_stage;
>
> if (var->data.location < VARYING_SLOT_VAR0 && var->data.location >= 0)
> continue;
> @@ -100,7 +111,7 @@ remove_unused_io_vars(nir_shader *shader, struct exec_list *var_list,
> if (var->data.always_active_io)
> continue;
>
> - uint64_t other_stage = used_by_other_stage[var->data.location_frac];
> + uint64_t other_stage = used[var->data.location_frac];
>
> if (!(other_stage & get_variable_io_mask(var, shader->info.stage))) {
> /* This one is invalid, make it a global variable instead */
> @@ -124,15 +135,26 @@ nir_remove_unused_varyings(nir_shader *producer, nir_shader *consumer)
> assert(consumer->info.stage != MESA_SHADER_VERTEX);
>
> uint64_t read[4] = { 0 }, written[4] = { 0 };
> + uint64_t patches_read[4] = { 0 }, patches_written[4] = { 0 };
>
> nir_foreach_variable(var, &producer->outputs) {
> - written[var->data.location_frac] |=
> - get_variable_io_mask(var, producer->info.stage);
> + if (var->data.patch) {
> + patches_written[var->data.location_frac] |=
> + get_variable_io_mask(var, producer->info.stage);
> + } else {
> + written[var->data.location_frac] |=
> + get_variable_io_mask(var, producer->info.stage);
> + }
> }
>
> nir_foreach_variable(var, &consumer->inputs) {
> - read[var->data.location_frac] |=
> - get_variable_io_mask(var, consumer->info.stage);
> + if (var->data.patch) {
> + patches_read[var->data.location_frac] |=
> + get_variable_io_mask(var, consumer->info.stage);
> + } else {
> + read[var->data.location_frac] |=
> + get_variable_io_mask(var, consumer->info.stage);
> + }
> }
>
> /* Each TCS invocation can read data written by other TCS invocations,
> @@ -140,13 +162,14 @@ nir_remove_unused_varyings(nir_shader *producer, nir_shader *consumer)
> * sure they are not read by the TCS before demoting them to globals.
> */
> if (producer->info.stage == MESA_SHADER_TESS_CTRL)
> - tcs_add_output_reads(producer, read);
> + tcs_add_output_reads(producer, read, patches_read);
>
> bool progress = false;
> - progress = remove_unused_io_vars(producer, &producer->outputs, read);
> + progress = remove_unused_io_vars(producer, &producer->outputs, read,
> + patches_read);
>
> - progress =
> - remove_unused_io_vars(consumer, &consumer->inputs, written) || progress;
> + progress = remove_unused_io_vars(consumer, &consumer->inputs, written,
> + patches_written) || progress;
>
> return progress;
> }
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list