[Mesa-dev] [PATCH v2 08/13] i965: Handle TCS outputs and TES inputs.

Jordan Justen jordan.l.justen at intel.com
Sat Dec 12 22:21:19 PST 2015


On 2015-12-11 13:23:57, Kenneth Graunke wrote:
> TCS outputs and TES inputs both refer to a common "patch URB entry"
> shared across all invocations.  First, there are some number of
> per-patch entries.  Then, there are per-vertex entries accessed via
> an offset for the variable and a stride times the vertex index.
> 
> Because these calculations need to be done in both the vec4 and scalar
> backends, it's simpler to just compute the offset calculations in NIR.
> It doesn't necessarily make much sense to use per-vertex intrinsics
> afterwards, but that at least means we don't lose the per-patch vs.
> per-vertex information.
> 
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
>  src/mesa/drivers/dri/i965/brw_nir.c | 122 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 120 insertions(+), 2 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c
> index 9cf4944..e46e177 100644
> --- a/src/mesa/drivers/dri/i965/brw_nir.c
> +++ b/src/mesa/drivers/dri/i965/brw_nir.c
> @@ -133,6 +133,69 @@ remap_inputs_with_vue_map(nir_block *block, void *closure)
>     return true;
>  }
>  
> +struct remap_patch_urb_offsets_state {
> +   nir_builder b;
> +   struct brw_vue_map vue_map;
> +};
> +
> +static bool
> +remap_patch_urb_offsets(nir_block *block, void *closure)
> +{
> +   struct remap_patch_urb_offsets_state *state = closure;
> +
> +   nir_foreach_instr_safe(block, instr) {
> +      if (instr->type != nir_instr_type_intrinsic)
> +         continue;
> +
> +      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
> +
> +      bool is_input =
> +         intrin->intrinsic == nir_intrinsic_load_input ||
> +         intrin->intrinsic == nir_intrinsic_load_per_vertex_input;
> +
> +      bool is_output =
> +         intrin->intrinsic == nir_intrinsic_load_output ||
> +         intrin->intrinsic == nir_intrinsic_load_per_vertex_output ||
> +         intrin->intrinsic == nir_intrinsic_store_output ||
> +         intrin->intrinsic == nir_intrinsic_store_per_vertex_output;

Can you call the functions you added previously? (i965: Separate base
offset/constant offset combining from remapping.)

7 & 8 Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>

> +
> +      if ((state->b.shader->stage == MESA_SHADER_TESS_CTRL && is_output) ||
> +          (state->b.shader->stage == MESA_SHADER_TESS_EVAL && is_input)) {
> +         int vue_slot = state->vue_map.varying_to_slot[intrin->const_index[0]];
> +         assert(vue_slot != -1);
> +         intrin->const_index[0] = vue_slot;
> +
> +         nir_src *vertex = nir_get_io_vertex_index_src(intrin);
> +         if (vertex) {
> +            nir_const_value *const_vertex = nir_src_as_const_value(*vertex);
> +            if (const_vertex) {
> +               intrin->const_index[0] += const_vertex->u[0] *
> +                                         state->vue_map.num_per_vertex_slots;
> +            } else {
> +               state->b.cursor = nir_before_instr(&intrin->instr);
> +
> +               /* Multiply by the number of per-vertex slots. */
> +               nir_ssa_def *vertex_offset =
> +                  nir_imul(&state->b,
> +                           nir_ssa_for_src(&state->b, *vertex, 1),
> +                           nir_imm_int(&state->b,
> +                                       state->vue_map.num_per_vertex_slots));
> +
> +               /* Add it to the existing offset */
> +               nir_src *offset = nir_get_io_offset_src(intrin);
> +               nir_ssa_def *total_offset =
> +                  nir_iadd(&state->b, vertex_offset,
> +                           nir_ssa_for_src(&state->b, *offset, 1));
> +
> +               nir_instr_rewrite_src(&intrin->instr, offset,
> +                                     nir_src_for_ssa(total_offset));
> +            }
> +         }
> +      }
> +   }
> +   return true;
> +}
> +
>  static void
>  brw_nir_lower_inputs(nir_shader *nir,
>                       const struct brw_device_info *devinfo,
> @@ -223,6 +286,31 @@ brw_nir_lower_inputs(nir_shader *nir,
>        }
>        break;
>     }
> +   case MESA_SHADER_TESS_EVAL: {
> +      struct remap_patch_urb_offsets_state state;
> +      brw_compute_tess_vue_map(&state.vue_map,
> +                               nir->info.inputs_read & ~VARYING_BIT_PRIMITIVE_ID,
> +                               nir->info.patch_inputs_read);
> +
> +      foreach_list_typed(nir_variable, var, node, &nir->inputs) {
> +         var->data.driver_location = var->data.location;
> +      }
> +
> +      nir_lower_io(nir, nir_var_shader_in, type_size_vec4);
> +
> +      /* This pass needs actual constants */
> +      nir_opt_constant_folding(nir);
> +
> +      nir_foreach_overload(nir, overload) {
> +         if (overload->impl) {
> +            nir_builder_init(&params.b, overload->impl);
> +            nir_foreach_block(overload->impl, add_const_offset_to_base, &params);
> +            nir_builder_init(&state.b, overload->impl);
> +            nir_foreach_block(overload->impl, remap_patch_urb_offsets, &state);
> +         }
> +      }
> +      break;
> +   }
>     case MESA_SHADER_FRAGMENT:
>        assert(is_scalar);
>        nir_assign_var_locations(&nir->inputs, &nir->num_inputs,
> @@ -238,7 +326,9 @@ brw_nir_lower_inputs(nir_shader *nir,
>  }
>  
>  static void
> -brw_nir_lower_outputs(nir_shader *nir, bool is_scalar)
> +brw_nir_lower_outputs(nir_shader *nir,
> +                      const struct brw_device_info *devinfo,
> +                      bool is_scalar)
>  {
>     switch (nir->stage) {
>     case MESA_SHADER_VERTEX:
> @@ -253,6 +343,34 @@ brw_nir_lower_outputs(nir_shader *nir, bool is_scalar)
>              var->data.driver_location = var->data.location;
>        }
>        break;
> +   case MESA_SHADER_TESS_CTRL: {
> +      struct add_const_offset_to_base_params params = {
> +         .mode = nir_var_shader_out
> +      };
> +
> +      struct remap_patch_urb_offsets_state state;
> +      brw_compute_tess_vue_map(&state.vue_map, nir->info.outputs_written,
> +                               nir->info.patch_outputs_written);
> +
> +      nir_foreach_variable(var, &nir->outputs) {
> +         var->data.driver_location = var->data.location;
> +      }
> +
> +      nir_lower_io(nir, nir_var_shader_out, type_size_vec4);
> +
> +      /* This pass needs actual constants */
> +      nir_opt_constant_folding(nir);
> +
> +      nir_foreach_overload(nir, overload) {
> +         if (overload->impl) {
> +            nir_builder_init(&params.b, overload->impl);
> +            nir_foreach_block(overload->impl, add_const_offset_to_base, &params);
> +            nir_builder_init(&state.b, overload->impl);
> +            nir_foreach_block(overload->impl, remap_patch_urb_offsets, &state);
> +         }
> +      }
> +      break;
> +   }
>     case MESA_SHADER_FRAGMENT:
>        nir_assign_var_locations(&nir->outputs, &nir->num_outputs,
>                                 type_size_scalar);
> @@ -420,7 +538,7 @@ brw_lower_nir(nir_shader *nir,
>     (void)progress;
>  
>     OPT_V(brw_nir_lower_inputs, devinfo, is_scalar);
> -   OPT_V(brw_nir_lower_outputs, is_scalar);
> +   OPT_V(brw_nir_lower_outputs, devinfo, is_scalar);
>     OPT_V(brw_nir_lower_uniforms, is_scalar);
>     OPT_V(nir_lower_io, nir_var_all, is_scalar ? type_size_scalar : type_size_vec4);
>  
> -- 
> 2.6.3
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list