[Mesa-dev] [PATCH 04/14] glsl_to_tgsi: reduce the size of st_dst_reg and st_src_reg

Nicolai Hähnle nhaehnle at gmail.com
Tue Oct 18 09:27:04 UTC 2016


On 17.10.2016 15:39, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> I noticed that glsl_to_tgsi_instruction is too huge.
>
> sizeof(glsl_to_tgsi_instruction): 752 -> 464 (-38%)
> ---
>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 71 +++++++++++++++++-------------
>  1 file changed, 40 insertions(+), 31 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 93673fa..78d9409 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -152,37 +152,38 @@ public:
>        this->reladdr = NULL;
>        this->reladdr2 = NULL;
>        this->has_index2 = false;
>        this->double_reg2 = false;
>        this->array_id = 0;
>        this->is_double_vertex_input = false;
>     }
>
>     explicit st_src_reg(st_dst_reg reg);
>
> -   gl_register_file file; /**< PROGRAM_* from Mesa */
> -   int index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
> -   int index2D;
> -   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
> -   int negate; /**< NEGATE_XYZW mask from mesa */
> -   enum glsl_base_type 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;
> -   st_src_reg *reladdr2;
> -   bool has_index2;
> +   int16_t index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
> +   int16_t index2D;

This reminds me that we really should have proper error handling for 
when these various numbers overflow. Anyway, patches 2-4:

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

> +   uint16_t swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
> +   int negate:4; /**< NEGATE_XYZW mask from mesa */
> +   enum glsl_base_type type:4; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
> +   unsigned has_index2:1;
> +   gl_register_file file:5; /**< PROGRAM_* from Mesa */
>     /*
>      * Is this the second half of a double register pair?
>      * currently used for input mapping only.
>      */
> -   bool double_reg2;
> -   unsigned array_id;
> -   bool is_double_vertex_input;
> +   unsigned double_reg2:1;
> +   unsigned is_double_vertex_input:1;
> +   unsigned array_id:10;
> +
> +   /** Register index should be offset by the integer in this reg. */
> +   st_src_reg *reladdr;
> +   st_src_reg *reladdr2;
>  };
>
>  class st_dst_reg {
>  public:
>     st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index)
>     {
>        assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
>        this->file = file;
>        this->index = index;
>        this->index2D = 0;
> @@ -216,30 +217,31 @@ public:
>        this->index2D = 0;
>        this->writemask = 0;
>        this->reladdr = NULL;
>        this->reladdr2 = NULL;
>        this->has_index2 = false;
>        this->array_id = 0;
>     }
>
>     explicit st_dst_reg(st_src_reg reg);
>
> -   gl_register_file file; /**< PROGRAM_* from Mesa */
> -   int index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
> -   int index2D;
> -   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
> -   enum glsl_base_type type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
> +   int16_t index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
> +   int16_t index2D;
> +   gl_register_file file:5; /**< PROGRAM_* from Mesa */
> +   unsigned writemask:4; /**< Bitfield of WRITEMASK_[XYZW] */
> +   enum glsl_base_type type:4; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
> +   unsigned has_index2:1;
> +   unsigned array_id:10;
> +
>     /** Register index should be offset by the integer in this reg. */
>     st_src_reg *reladdr;
>     st_src_reg *reladdr2;
> -   bool has_index2;
> -   unsigned array_id;
>  };
>
>  st_src_reg::st_src_reg(st_dst_reg reg)
>  {
>     this->type = reg.type;
>     this->file = reg.file;
>     this->index = reg.index;
>     this->swizzle = SWIZZLE_XYZW;
>     this->negate = 0;
>     this->reladdr = reg.reladdr;
> @@ -445,21 +447,21 @@ public:
>
>     int glsl_version;
>     bool native_integers;
>     bool have_sqrt;
>     bool have_fma;
>     bool use_shared_memory;
>
>     variable_storage *find_variable_storage(ir_variable *var);
>
>     int add_constant(gl_register_file file, gl_constant_value values[8],
> -                    int size, int datatype, GLuint *swizzle_out);
> +                    int size, int datatype, uint16_t *swizzle_out);
>
>     function_entry *get_function_signature(ir_function_signature *sig);
>
>     st_src_reg get_temp(const glsl_type *type);
>     void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr);
>
>     st_src_reg st_src_reg_for_double(double val);
>     st_src_reg st_src_reg_for_float(float val);
>     st_src_reg st_src_reg_for_int(int val);
>     st_src_reg st_src_reg_for_type(enum glsl_base_type type, int val);
> @@ -549,25 +551,25 @@ public:
>                      st_dst_reg dst, st_src_reg src0);
>
>     void emit_scalar(ir_instruction *ir, unsigned op,
>                      st_dst_reg dst, st_src_reg src0, st_src_reg src1);
>
>     void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0);
>
>     void get_deref_offsets(ir_dereference *ir,
>                            unsigned *array_size,
>                            unsigned *base,
> -                          unsigned *index,
> +                          uint16_t *index,
>                            st_src_reg *reladdr);
>    void calc_deref_offsets(ir_dereference *tail,
>                            unsigned *array_elements,
> -                          unsigned *index,
> +                          uint16_t *index,
>                            st_src_reg *indirect,
>                            unsigned *location);
>     st_src_reg canonicalize_gather_offset(st_src_reg offset);
>
>     bool try_emit_mad(ir_expression *ir,
>                int mul_operand);
>     bool try_emit_mad_for_and_not(ir_expression *ir,
>                int mul_operand);
>
>     void emit_swz(ir_expression *ir);
> @@ -1100,25 +1102,29 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
>     assert(dst.file == PROGRAM_ADDRESS);
>     if (dst.index >= this->num_address_regs)
>        this->num_address_regs = dst.index + 1;
>
>     emit_asm(NULL, op, dst, src0);
>  }
>
>  int
>  glsl_to_tgsi_visitor::add_constant(gl_register_file file,
>                                     gl_constant_value values[8], int size, int datatype,
> -                                   GLuint *swizzle_out)
> +                                   uint16_t *swizzle_out)
>  {
>     if (file == PROGRAM_CONSTANT) {
> -      return _mesa_add_typed_unnamed_constant(this->prog->Parameters, values,
> -                                              size, datatype, swizzle_out);
> +      GLuint swizzle = swizzle_out ? *swizzle_out : 0;
> +      int result = _mesa_add_typed_unnamed_constant(this->prog->Parameters, values,
> +                                                    size, datatype, &swizzle);
> +      if (swizzle_out)
> +         *swizzle_out = swizzle;
> +      return result;
>     }
>
>     assert(file == PROGRAM_IMMEDIATE);
>
>     int index = 0;
>     immediate_storage *entry;
>     int size32 = size * (datatype == GL_DOUBLE ? 2 : 1);
>     int i;
>
>     /* Search immediate storage to see if we already have an identical
> @@ -3225,21 +3231,22 @@ glsl_to_tgsi_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
>  {
>     exec_node *param = ir->actual_parameters.get_head();
>     ir_dereference *deref = static_cast<ir_dereference *>(param);
>     ir_variable *location = deref->variable_referenced();
>
>     st_src_reg buffer(
>           PROGRAM_BUFFER, location->data.binding, GLSL_TYPE_ATOMIC_UINT);
>
>     /* Calculate the surface offset */
>     st_src_reg offset;
> -   unsigned array_size = 0, base = 0, index = 0;
> +   unsigned array_size = 0, base = 0;
> +   uint16_t index = 0;
>
>     get_deref_offsets(deref, &array_size, &base, &index, &offset);
>
>     if (offset.file != PROGRAM_UNDEFINED) {
>        emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(offset),
>                 offset, st_src_reg_for_int(ATOMIC_COUNTER_SIZE));
>        emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(offset),
>                 offset, st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE));
>     } else {
>        offset = st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE);
> @@ -3558,21 +3565,22 @@ glsl_to_tgsi_visitor::visit_image_intrinsic(ir_call *ir)
>
>     ir_dereference *img = (ir_dereference *)param;
>     const ir_variable *imgvar = img->variable_referenced();
>     const glsl_type *type = imgvar->type->without_array();
>     unsigned sampler_array_size = 1, sampler_base = 0;
>
>     st_src_reg reladdr;
>     st_src_reg image(PROGRAM_IMAGE, 0, GLSL_TYPE_UINT);
>
>     get_deref_offsets(img, &sampler_array_size, &sampler_base,
> -                     (unsigned int *)&image.index, &reladdr);
> +                     (uint16_t*)&image.index, &reladdr);
> +
>     if (reladdr.file != PROGRAM_UNDEFINED) {
>        image.reladdr = ralloc(mem_ctx, st_src_reg);
>        *image.reladdr = reladdr;
>        emit_arl(ir, sampler_reladdr, reladdr);
>     }
>
>     st_dst_reg dst = undef_dst;
>     if (ir->return_deref) {
>        ir->return_deref->accept(this);
>        dst = st_dst_reg(this->result);
> @@ -3878,21 +3886,21 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
>        }
>     }
>
>     /* Process return value. */
>     this->result = entry->return_reg;
>  }
>
>  void
>  glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
>                                           unsigned *array_elements,
> -                                         unsigned *index,
> +                                         uint16_t *index,
>                                           st_src_reg *indirect,
>                                           unsigned *location)
>  {
>     switch (tail->ir_type) {
>     case ir_type_dereference_record: {
>        ir_dereference_record *deref_record = tail->as_dereference_record();
>        const glsl_type *struct_type = deref_record->record->type;
>        int field_index = deref_record->record->type->field_index(deref_record->field);
>
>        calc_deref_offsets(deref_record->record->as_dereference(), array_elements, index, indirect, location);
> @@ -3937,21 +3945,21 @@ glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
>     }
>     default:
>        break;
>     }
>  }
>
>  void
>  glsl_to_tgsi_visitor::get_deref_offsets(ir_dereference *ir,
>                                          unsigned *array_size,
>                                          unsigned *base,
> -                                        unsigned *index,
> +                                        uint16_t *index,
>                                          st_src_reg *reladdr)
>  {
>     GLuint shader = _mesa_program_enum_to_shader_stage(this->prog->Target);
>     unsigned location = 0;
>     ir_variable *var = ir->variable_referenced();
>
>     memset(reladdr, 0, sizeof(*reladdr));
>     reladdr->file = PROGRAM_UNDEFINED;
>
>     *base = 0;
> @@ -3993,21 +4001,22 @@ glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
>  void
>  glsl_to_tgsi_visitor::visit(ir_texture *ir)
>  {
>     st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy;
>     st_src_reg offset[MAX_GLSL_TEXTURE_OFFSET], sample_index, component;
>     st_src_reg levels_src, reladdr;
>     st_dst_reg result_dst, coord_dst, cube_sc_dst;
>     glsl_to_tgsi_instruction *inst = NULL;
>     unsigned opcode = TGSI_OPCODE_NOP;
>     const glsl_type *sampler_type = ir->sampler->type;
> -   unsigned sampler_array_size = 1, sampler_index = 0, sampler_base = 0;
> +   unsigned sampler_array_size = 1, sampler_base = 0;
> +   uint16_t sampler_index = 0;
>     bool is_cube_array = false;
>     unsigned i;
>
>     /* if we are a cube array sampler */
>     if ((sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE &&
>          sampler_type->sampler_array)) {
>        is_cube_array = true;
>     }
>
>     if (ir->coordinate) {
>


More information about the mesa-dev mailing list