[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