[Mesa-dev] [PATCH 4/7] glsl_to_tgsi: allocate arrays separately

Christian König deathsimple at vodafone.de
Mon Mar 11 05:44:51 PDT 2013


From: Christian König <christian.koenig at amd.com>

Instead of allocating everything as temporaries, use the
new array allocation functions.

Signed-off-by: Christian König <christian.koenig at amd.com>
---
 src/mesa/main/mtypes.h                     |    1 +
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |   83 ++++++++++++++++++----------
 2 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4f09513..f7499d0 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1905,6 +1905,7 @@ struct gl_transform_feedback_state
 typedef enum
 {
    PROGRAM_TEMPORARY,   /**< machine->Temporary[] */
+   PROGRAM_ARRAY,       /**< Arrays & Matrixes */
    PROGRAM_INPUT,       /**< machine->Inputs[] */
    PROGRAM_OUTPUT,      /**< machine->Outputs[] */
    PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index b2cccbc..ce90188 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -85,6 +85,11 @@ extern "C" {
  */
 #define MAX_TEMPS         4096
 
+/**
+ * Maximum number of arrays
+ */
+#define MAX_ARRAYS        256
+
 /* will be 4 for GLSL 4.00 */
 #define MAX_GLSL_TEXTURE_OFFSET 1
 
@@ -315,6 +320,9 @@ public:
 
    int next_temp;
 
+   unsigned array_sizes[MAX_ARRAYS];
+   unsigned next_array;
+
    int num_address_regs;
    int samplers_used;
    bool indirect_addr_temps;
@@ -550,6 +558,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
    if (dst.reladdr) {
       switch(dst.file) {
       case PROGRAM_TEMPORARY:
+      case PROGRAM_ARRAY:
          this->indirect_addr_temps = true;
          break;
       case PROGRAM_LOCAL_PARAM:
@@ -571,6 +580,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
          if(inst->src[i].reladdr) {
             switch(inst->src[i].file) {
             case PROGRAM_TEMPORARY:
+            case PROGRAM_ARRAY:
                this->indirect_addr_temps = true;
                break;
             case PROGRAM_LOCAL_PARAM:
@@ -1005,17 +1015,26 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
    st_src_reg src;
 
    src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT;
-   src.file = PROGRAM_TEMPORARY;
-   src.index = next_temp;
    src.reladdr = NULL;
-   next_temp += type_size(type);
+   src.negate = 0;
+
+   if (type->is_array() || type->is_matrix()) {
+      src.file = PROGRAM_ARRAY;
+      src.index = next_array << 16 | 0x8000;
+      array_sizes[next_array] = type_size(type);
+      ++next_array;
+
+   } else {
+      src.file = PROGRAM_TEMPORARY;
+      src.index = next_temp;
+      next_temp += type_size(type);
+   }
 
    if (type->is_array() || type->is_record()) {
       src.swizzle = SWIZZLE_NOOP;
    } else {
       src.swizzle = swizzle_for_size(type->vector_elements);
    }
-   src.negate = 0;
 
    return src;
 }
@@ -2975,6 +2994,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
 {
    result.file = PROGRAM_UNDEFINED;
    next_temp = 1;
+   next_array = 0;
    next_signature_id = 1;
    num_immediates = 0;
    current_function = NULL;
@@ -4011,6 +4031,7 @@ struct st_translate {
    struct ureg_program *ureg;
 
    struct ureg_dst temps[MAX_TEMPS];
+   struct ureg_dst arrays[MAX_ARRAYS];
    struct ureg_src *constants;
    struct ureg_src *immediates;
    struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
@@ -4129,16 +4150,30 @@ dst_register(struct st_translate *t,
              gl_register_file file,
              GLuint index)
 {
+   unsigned array;
+
    switch(file) {
    case PROGRAM_UNDEFINED:
       return ureg_dst_undef();
 
    case PROGRAM_TEMPORARY:
+      assert(index >= 0);
+      assert(index < (int) Elements(t->temps));
+ 
       if (ureg_dst_is_undef(t->temps[index]))
          t->temps[index] = ureg_DECL_local_temporary(t->ureg);
 
       return t->temps[index];
 
+   case PROGRAM_ARRAY:
+      array = index >> 16;
+
+      assert(array >= 0);
+      assert(array < (int) Elements(t->arrays));
+
+      return ureg_dst_array_offset(t->arrays[array],
+                                   (int)(index & 0xFFFF) - 0x8000);
+
    case PROGRAM_OUTPUT:
       if (t->procType == TGSI_PROCESSOR_VERTEX)
          assert(index < VERT_RESULT_MAX);
@@ -4173,11 +4208,8 @@ src_register(struct st_translate *t,
       return ureg_src_undef();
 
    case PROGRAM_TEMPORARY:
-      assert(index >= 0);
-      assert(index < (int) Elements(t->temps));
-      if (ureg_dst_is_undef(t->temps[index]))
-         t->temps[index] = ureg_DECL_local_temporary(t->ureg);
-      return ureg_src(t->temps[index]);
+   case PROGRAM_ARRAY:
+      return ureg_src(dst_register(t, file, index));
 
    case PROGRAM_ENV_PARAM:
    case PROGRAM_LOCAL_PARAM:
@@ -4259,8 +4291,10 @@ translate_dst(struct st_translate *t,
       }
    }
 
-   if (dst_reg->reladdr != NULL)
+   if (dst_reg->reladdr != NULL) {
+      assert(dst_reg->file != PROGRAM_TEMPORARY);
       dst = ureg_dst_indirect(dst, ureg_src(t->address[0]));
+   }
 
    return dst;
 }
@@ -4283,26 +4317,8 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
       src = ureg_negate(src);
 
    if (src_reg->reladdr != NULL) {
-      /* Normally ureg_src_indirect() would be used here, but a stupid compiler 
-       * bug in g++ makes ureg_src_indirect (an inline C function) erroneously 
-       * set the bit for src.Negate.  So we have to do the operation manually
-       * here to work around the compiler's problems. */
-      /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/
-      struct ureg_src addr = ureg_src(t->address[0]);
-      src.Indirect = 1;
-      src.IndirectFile = addr.File;
-      src.IndirectIndex = addr.Index;
-      src.IndirectSwizzle = addr.SwizzleX;
-      
-      if (src_reg->file != PROGRAM_INPUT &&
-          src_reg->file != PROGRAM_OUTPUT) {
-         /* If src_reg->index was negative, it was set to zero in
-          * src_register().  Reassign it now.  But don't do this
-          * for input/output regs since they get remapped while
-          * const buffers don't.
-          */
-         src.Index = src_reg->index;
-      }
+      assert(src_reg->file != PROGRAM_TEMPORARY);
+      src = ureg_src_indirect(src, ureg_src(t->address[0]));
    }
 
    return src;
@@ -4783,6 +4799,13 @@ st_translate_program(
       t->address[0] = ureg_DECL_address(ureg);
    }
 
+   /* Declare arrays
+    */
+   for (i = 0; i < program->next_array; ++i) {
+     t->arrays[i] = ureg_DECL_array_temporary(t->ureg, program->array_sizes[i],
+                                              TRUE);
+   }
+
    /* Declare misc input registers
     */
    {
-- 
1.7.9.5



More information about the mesa-dev mailing list