[Mesa-dev] [PATCH] glsl_to_tgsi: indirect array information

Connor Abbott cwabbott0 at gmail.com
Mon Jan 21 12:30:30 PST 2013


Hi,

I'm not very familiar with the code, but I should mention that this should
really help with the lima compiler backend. In fact, I was thinking of this
very problem recently when figuring out how to translate TGSI into our
backend. Fragment shaders on the Mali 200/400 have 6 vector registers,
which cannot be indirectly addressed, and a large array of temporaries
which can (and a similar situation for vertex shaders), so we need this
information to determine whether we should use a register or temporary to
hold each value. Basically, something like this is a prerequisite for a
lima Gallium3D driver (assuming we go down that path).

Connor Abbott

On Mon, Jan 21, 2013 at 3:10 PM, Vadim Girlin <vadimgirlin at gmail.com> wrote:

> Provide the information about indirectly addressable arrays (ranges of
> temps) in
> the shader to the drivers. TGSI representation itself isn't modified, array
> information is passed as an additional data in the pipe_shader_state, so
> the
> drivers can use it as a hint for optimization.
> ---
>
> It's far from being an ideal solution, but I saw the discussions about that
> problem starting from 2009 IIRC, and we still have no solution (neither
> good
> nor bad) despite the years passed. I hope we can use this not very
> intrusive
> approach until we get something better.
>
>  src/gallium/auxiliary/tgsi/tgsi_ureg.c     |  2 ++
>  src/gallium/include/pipe/p_state.h         | 13 +++++++
>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 57
> +++++++++++++++++++++++++-----
>  src/mesa/state_tracker/st_program.c        |  4 +++
>  src/mesa/state_tracker/st_program.h        |  1 +
>  5 files changed, 69 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> index 3c2a923..61db431 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> @@ -1658,6 +1658,8 @@ void *ureg_create_shader( struct ureg_program *ureg,
>     else
>        memset(&state.stream_output, 0, sizeof(state.stream_output));
>
> +   memset(&state.array_info, 0, sizeof(state.array_info));
> +
>     if (ureg->processor == TGSI_PROCESSOR_VERTEX)
>        return pipe->create_vs_state( pipe, &state );
>     else
> diff --git a/src/gallium/include/pipe/p_state.h
> b/src/gallium/include/pipe/p_state.h
> index ab49cab..4490f2e 100644
> --- a/src/gallium/include/pipe/p_state.h
> +++ b/src/gallium/include/pipe/p_state.h
> @@ -65,6 +65,8 @@ extern "C" {
>  #define PIPE_MAX_TEXTURE_LEVELS   16
>  #define PIPE_MAX_SO_BUFFERS        4
>
> +#define PIPE_MAX_INDIRECT_ARRAYS  16
> +
>
>  struct pipe_reference
>  {
> @@ -205,11 +207,22 @@ struct pipe_stream_output_info
>     } output[PIPE_MAX_SHADER_OUTPUTS];
>  };
>
> +struct pipe_shader_indirect_array {
> +   unsigned index:16;
> +   unsigned size:16;
> +};
> +
> +struct pipe_shader_array_info
> +{
> +   struct pipe_shader_indirect_array arrays[PIPE_MAX_INDIRECT_ARRAYS];
> +   unsigned num_arrays;
> +};
>
>  struct pipe_shader_state
>  {
>     const struct tgsi_token *tokens;
>     struct pipe_stream_output_info stream_output;
> +   struct pipe_shader_array_info array_info;
>  };
>
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 1d96e90..4ded1be 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -110,6 +110,7 @@ public:
>        this->index2D = 0;
>        this->type = type ? type->base_type : GLSL_TYPE_ERROR;
>        this->reladdr = NULL;
> +      this->size = 0;
>     }
>
>     st_src_reg(gl_register_file file, int index, int type)
> @@ -121,6 +122,7 @@ public:
>        this->swizzle = SWIZZLE_XYZW;
>        this->negate = 0;
>        this->reladdr = NULL;
> +      this->size = 0;
>     }
>
>     st_src_reg(gl_register_file file, int index, int type, int index2D)
> @@ -132,6 +134,7 @@ public:
>        this->swizzle = SWIZZLE_XYZW;
>        this->negate = 0;
>        this->reladdr = NULL;
> +      this->size = 0;
>     }
>
>     st_src_reg()
> @@ -143,6 +146,7 @@ public:
>        this->swizzle = 0;
>        this->negate = 0;
>        this->reladdr = NULL;
> +      this->size = 0;
>     }
>
>     explicit st_src_reg(st_dst_reg reg);
> @@ -155,6 +159,7 @@ public:
>     int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
>     /** Register index should be offset by the integer in this reg. */
>     st_src_reg *reladdr;
> +   int size;
>  };
>
>  class st_dst_reg {
> @@ -244,8 +249,9 @@ public:
>
>  class variable_storage : public exec_node {
>  public:
> -   variable_storage(ir_variable *var, gl_register_file file, int index)
> -      : file(file), index(index), var(var)
> +   variable_storage(ir_variable *var, gl_register_file file, int index,
> +                    int size = 0)
> +      : file(file), index(index), var(var), size(size)
>     {
>        /* empty */
>     }
> @@ -253,6 +259,7 @@ public:
>     gl_register_file file;
>     int index;
>     ir_variable *var; /* variable that maps to this, if any */
> +   int size;
>  };
>
>  class immediate_storage : public exec_node {
> @@ -312,6 +319,7 @@ public:
>     struct gl_program *prog;
>     struct gl_shader_program *shader_program;
>     struct gl_shader_compiler_options *options;
> +   struct pipe_shader_array_info array_info;
>
>     int next_temp;
>
> @@ -445,6 +453,8 @@ public:
>     void emit_block_mov(ir_assignment *ir, const struct glsl_type *type,
>                         st_dst_reg *l, st_src_reg *r);
>
> +   void add_array_info(const st_src_reg *src);
> +
>     void *mem_ctx;
>  };
>
> @@ -1004,7 +1014,8 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
>     src.file = PROGRAM_TEMPORARY;
>     src.index = next_temp;
>     src.reladdr = NULL;
> -   next_temp += type_size(type);
> +   src.size = type_size(type);
> +   next_temp += src.size;
>
>     if (type->is_array() || type->is_record()) {
>        src.swizzle = SWIZZLE_NOOP;
> @@ -1075,9 +1086,10 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
>           assert((int) ir->num_state_slots == type_size(ir->type));
>
>           storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY,
> -                                                this->next_temp);
> +                                                 this->next_temp,
> +                                                 type_size(ir->type));
>           this->variables.push_tail(storage);
> -         this->next_temp += type_size(ir->type);
> +         this->next_temp += storage->size;
>
>           dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index,
>                 native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT));
> @@ -2029,10 +2041,10 @@
> glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
>        case ir_var_auto:
>        case ir_var_temporary:
>           entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY,
> -                                              this->next_temp);
> +                                               this->next_temp,
> +                                               type_size(var->type));
>           this->variables.push_tail(entry);
> -
> -         next_temp += type_size(var->type);
> +         next_temp += entry->size;
>           break;
>        }
>
> @@ -2043,6 +2055,8 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable
> *ir)
>     }
>
>     this->result = st_src_reg(entry->file, entry->index, var->type);
> +   this->result.size = entry->size;
> +
>     if (!native_integers)
>        this->result.type = GLSL_TYPE_FLOAT;
>  }
> @@ -2062,12 +2076,16 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array
> *ir)
>     if (index) {
>        src.index += index->value.i[0] * element_size;
>     } else {
> +
>        /* Variable index array dereference.  It eats the "vec4" of the
>         * base of the array and an index that offsets the TGSI register
>         * index.
>         */
>        ir->array_index->accept(this);
>
> +      if (src.size > 1 && src.file == PROGRAM_TEMPORARY)
> +         add_array_info(&src);
> +
>        st_src_reg index_reg;
>
>        if (element_size == 1) {
> @@ -2969,6 +2987,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
>     prog = NULL;
>     shader_program = NULL;
>     options = NULL;
> +   array_info.num_arrays = 0;
>  }
>
>  glsl_to_tgsi_visitor::~glsl_to_tgsi_visitor()
> @@ -3771,6 +3790,23 @@ glsl_to_tgsi_visitor::renumber_registers(void)
>     this->next_temp = new_index;
>  }
>
> +void
> +glsl_to_tgsi_visitor::add_array_info(const st_src_reg *src)
> +{
> +   unsigned i;
> +
> +   if (array_info.num_arrays == PIPE_MAX_INDIRECT_ARRAYS)
> +      return;
> +
> +   for (i = 0; i < array_info.num_arrays; ++i) {
> +      if (array_info.arrays[i].index == (unsigned)src->index)
> +         return;
> +   }
> +   array_info.arrays[i].index = src->index;
> +   array_info.arrays[i].size = src->size;
> +   ++array_info.num_arrays;
> +}
> +
>  /**
>   * Returns a fragment program which implements the current pixel transfer
> ops.
>   * Based on get_pixel_transfer_program in st_atom_pixeltransfer.c.
> @@ -4798,6 +4834,11 @@ st_translate_program(
>     }
>
>     if (program->indirect_addr_temps) {
> +      struct pipe_shader_array_info *ai =
> +         &((struct st_fragment_program*) proginfo)->array_info;
> +
> +      memcpy(ai, &program->array_info, sizeof(struct
> pipe_shader_array_info));
> +
>        /* If temps are accessed with indirect addressing, declare
> temporaries
>         * in sequential order.  Else, we declare them on demand elsewhere.
>         * (Note: the number of temporaries is equal to program->next_temp)
> diff --git a/src/mesa/state_tracker/st_program.c
> b/src/mesa/state_tracker/st_program.c
> index a9111b5..1370c76 100644
> --- a/src/mesa/state_tracker/st_program.c
> +++ b/src/mesa/state_tracker/st_program.c
> @@ -739,6 +739,10 @@ st_translate_fragment_program(struct st_context *st,
>                                  fs_output_semantic_index, FALSE,
>                                  key->clamp_color);
>
> +   if (stfp->glsl_to_tgsi)
> +      memcpy(&variant->tgsi.array_info, &stfp->array_info,
> +             sizeof(struct pipe_shader_array_info));
> +
>     variant->tgsi.tokens = ureg_get_tokens( ureg, NULL );
>     ureg_destroy( ureg );
>
> diff --git a/src/mesa/state_tracker/st_program.h
> b/src/mesa/state_tracker/st_program.h
> index 23a262c..d6b2b0f 100644
> --- a/src/mesa/state_tracker/st_program.h
> +++ b/src/mesa/state_tracker/st_program.h
> @@ -90,6 +90,7 @@ struct st_fragment_program
>  {
>     struct gl_fragment_program Base;
>     struct glsl_to_tgsi_visitor* glsl_to_tgsi;
> +   struct pipe_shader_array_info array_info;
>
>     struct st_fp_variant *variants;
>  };
> --
> 1.8.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130121/af11b773/attachment-0001.html>


More information about the mesa-dev mailing list