[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