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

Marek Olšák maraeo at gmail.com
Mon Oct 17 13:39:16 UTC 2016


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;
+   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) {
-- 
2.7.4



More information about the mesa-dev mailing list