<p dir="ltr"><br>
On Aug 17, 2015 4:08 PM, "Kenneth Graunke" <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>> wrote:<br>
><br>
> Previously, we used nir_lower_io with the scalar type_size function,<br>
> which mapped VERT_ATTRIB_* locations to...some numbers.  Then, in<br>
> fs_visitor::nir_setup_inputs(), we created temporaries indexed by<br>
> those numbers, and emitted MOVs from the actual ATTR registers to<br>
> those temporaries.<br>
><br>
> This patch reworks our input lowering to produce NIR lower_input<br>
> intrinsics that properly index into the ATTR file, so we can access<br>
> it directly.<br>
><br>
> No changes in shader-db.<br>
><br>
> Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
> ---<br>
>  src/mesa/drivers/dri/i965/brw_fs.cpp     |  2 +-<br>
>  src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 71 +++++++++-----------------------<br>
>  src/mesa/drivers/dri/i965/brw_nir.c      | 25 ++++++++++-<br>
>  3 files changed, 45 insertions(+), 53 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> index 93adbc6..efabb52 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> @@ -4527,7 +4527,7 @@ fs_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)<br>
>           fprintf(file, "***m%d***", inst->src[i].reg);<br>
>           break;<br>
>        case ATTR:<br>
> -         fprintf(file, "attr%d", inst->src[i].reg + inst->src[i].reg_offset);<br>
> +         fprintf(file, "attr%d+%d", inst->src[i].reg, inst->src[i].reg_offset);<br>
>           break;<br>
>        case UNIFORM:<br>
>           fprintf(file, "u%d", inst->src[i].reg + inst->src[i].reg_offset);<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> index 51ba23b..397cdcb 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> @@ -56,61 +56,25 @@ fs_visitor::emit_nir_code()<br>
>  void<br>
>  fs_visitor::nir_setup_inputs(nir_shader *shader)<br>
>  {<br>
> +   if (stage != MESA_SHADER_FRAGMENT)<br>
> +      return;<br>
> +<br>
>     nir_inputs = bld.vgrf(BRW_REGISTER_TYPE_F, shader->num_inputs);<br>
><br>
>     foreach_list_typed(nir_variable, var, node, &shader->inputs) {<br>
> -      enum brw_reg_type type = brw_type_for_base_type(var->type);<br>
>        fs_reg input = offset(nir_inputs, bld, var->data.driver_location);<br>
><br>
>        fs_reg reg;<br>
> -      switch (stage) {<br>
> -      case MESA_SHADER_VERTEX: {<br>
> -         /* Our ATTR file is indexed by VERT_ATTRIB_*, which is the value<br>
> -          * stored in nir_variable::location.<br>
> -          *<br>
> -          * However, NIR's load_input intrinsics use a different index - an<br>
> -          * offset into a single contiguous array containing all inputs.<br>
> -          * This index corresponds to the nir_variable::driver_location field.<br>
> -          *<br>
> -          * So, we need to copy from fs_reg(ATTR, var->location) to<br>
> -          * offset(nir_inputs, var->data.driver_location).<br>
> -          */<br>
> -         const glsl_type *const t = var->type->without_array();<br>
> -         const unsigned components = t->components();<br>
> -         const unsigned cols = t->matrix_columns;<br>
> -         const unsigned elts = t->vector_elements;<br>
> -         unsigned array_length = var->type->is_array() ? var->type->length : 1;<br>
> -         for (unsigned i = 0; i < array_length; i++) {<br>
> -            for (unsigned j = 0; j < cols; j++) {<br>
> -               for (unsigned k = 0; k < elts; k++) {<br>
> -                  bld.MOV(offset(retype(input, type), bld,<br>
> -                                 components * i + elts * j + k),<br>
> -                          offset(fs_reg(ATTR, var->data.location + i, type),<br>
> -                                 bld, 4 * j + k));<br>
> -               }<br>
> -            }<br>
> -         }<br>
> -         break;<br>
> -      }<br>
> -      case MESA_SHADER_GEOMETRY:<br>
> -      case MESA_SHADER_COMPUTE:<br>
> -      case MESA_SHADER_TESS_CTRL:<br>
> -      case MESA_SHADER_TESS_EVAL:<br>
> -         unreachable("fs_visitor not used for these stages yet.");<br>
> -         break;<br>
> -      case MESA_SHADER_FRAGMENT:<br>
> -         if (var->data.location == VARYING_SLOT_POS) {<br>
> -            reg = *emit_fragcoord_interpolation(var->data.pixel_center_integer,<br>
> -                                                var->data.origin_upper_left);<br>
> -            emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(),<br>
> -                                      input, reg), 0xF);<br>
> -         } else {<br>
> -            emit_general_interpolation(input, var->name, var->type,<br>
> -                                       (glsl_interp_qualifier) var->data.interpolation,<br>
> -                                       var->data.location, var->data.centroid,<br>
> -                                       var->data.sample);<br>
> -         }<br>
> -         break;<br>
> +      if (var->data.location == VARYING_SLOT_POS) {<br>
> +         reg = *emit_fragcoord_interpolation(var->data.pixel_center_integer,<br>
> +                                             var->data.origin_upper_left);<br>
> +         emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(),<br>
> +                                   input, reg), 0xF);<br>
> +      } else {<br>
> +         emit_general_interpolation(input, var->name, var->type,<br>
> +                                    (glsl_interp_qualifier) var->data.interpolation,<br>
> +                                    var->data.location, var->data.centroid,<br>
> +                                    var->data.sample);<br>
>        }<br>
>     }<br>
>  }<br>
> @@ -1557,8 +1521,13 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr<br>
>     case nir_intrinsic_load_input: {<br>
>        unsigned index = 0;<br>
>        for (unsigned j = 0; j < instr->num_components; j++) {<br>
> -         fs_reg src = offset(retype(nir_inputs, dest.type), bld,<br>
> -                             instr->const_index[0] + index);<br>
> +         fs_reg src;<br>
> +         if (stage == MESA_SHADER_VERTEX) {<br>
> +            src = offset(fs_reg(ATTR, instr->const_index[0], dest.type), bld, index);<br>
> +         } else {<br>
> +            src = offset(retype(nir_inputs, dest.type), bld,<br>
> +                         instr->const_index[0] + index);<br>
> +         }<br>
>           if (has_indirect)<br>
>              src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));<br>
>           index++;<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c<br>
> index 224c207..2e2d02b 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_nir.c<br>
> +++ b/src/mesa/drivers/dri/i965/brw_nir.c<br>
> @@ -28,14 +28,37 @@<br>
>  #include "program/prog_to_nir.h"<br>
><br>
>  static void<br>
> +lower_scalar_vs_inputs(nir_shader *nir)<br>
> +{<br>
> +   /* Start with the location of the variable's base. */<br>
> +   foreach_list_typed(nir_variable, var, node, &nir->inputs) {<br>
> +      var->data.driver_location = var->data.location;<br>
> +   }<br>
> +<br>
> +   /* Now use nir_lower_io to walk dereference chains.  Attribute arrays<br>
> +    * are loaded as one vec4 per element (or matrix column), so we use<br>
> +    * type_size_vec4 here.<br>
> +    */<br>
> +   nir_lower_io(nir, nir_var_shader_in, type_size_vec4);<br>
> +}</p>
<p dir="ltr">I think I'd rather leave this inline and not split it out. It's easier to see the interactions that way.</p>
<p dir="ltr">> +<br>
> +static void<br>
>  brw_lower_nir_io_scalar(nir_shader *nir, gl_shader_stage stage)<br>
>  {<br>
>     nir_assign_var_locations_direct_first(nir, &nir->uniforms,<br>
>                                           &nir->num_direct_uniforms,<br>
>                                           &nir->num_uniforms,<br>
>                                           type_size_scalar);<br>
> -   nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_scalar);<br>
>     nir_assign_var_locations(&nir->outputs, &nir->num_outputs, type_size_scalar);<br>
> +<br>
> +   switch (stage) {<br>
> +   case MESA_SHADER_VERTEX:<br>
> +      lower_scalar_vs_inputs(nir);<br>
> +      break;<br>
> +   default:<br>
> +      nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_scalar);</p>
<p dir="ltr">Again, is "regular" lowering really the right default here?  It seems FS-specific...</p>
<p dir="ltr">> +      break;<br>
> +   }<br>
>     nir_lower_io(nir, -1, type_size_scalar);<br>
>  }<br>
><br>
> --<br>
> 2.5.0<br>
><br>
> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</p>