[Mesa-dev] [PATCH 2/2] gallium: improves glsl_to_tgsi generation of ARL

Vincent Lejeune vljn at ovi.com
Thu Dec 29 11:26:09 PST 2011


This commit should generates less ARL instructions when dealing with indirect
addressing.

v2: fix glsl-fs-uniform-array-4 piglit test
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |   56 +++++++++++++++++-----------
 1 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 3523159..0027396 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -482,6 +482,8 @@ static st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR);
 static st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR);
 
 static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT);
+static int available_address_writemask = WRITEMASK_X;
+static GLuint available_address_swizzle = SWIZZLE_X;
 
 static void
 fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3);
@@ -743,29 +745,10 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
         		 st_src_reg src0, st_src_reg src1, st_src_reg src2)
 {
    glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction();
-   int num_reladdr = 0, i;
+   int i;
    
    op = get_opcode(ir, op, dst, src0, src1);
 
-   /* If we have to do relative addressing, we want to load the ARL
-    * reg directly for one of the regs, and preload the other reladdr
-    * sources into temps.
-    */
-   num_reladdr += dst.reladdr != NULL;
-   num_reladdr += src0.reladdr != NULL;
-   num_reladdr += src1.reladdr != NULL;
-   num_reladdr += src2.reladdr != NULL;
-
-   reladdr_to_temp(ir, &src2, &num_reladdr);
-   reladdr_to_temp(ir, &src1, &num_reladdr);
-   reladdr_to_temp(ir, &src0, &num_reladdr);
-
-   if (dst.reladdr) {
-      emit_arl(ir, address_reg, *dst.reladdr);
-      num_reladdr--;
-   }
-   assert(num_reladdr == 0);
-
    inst->op = op;
    inst->dst = dst;
    inst->src[0] = src0;
@@ -2108,6 +2091,31 @@ glsl_to_tgsi_visitor::visit(ir_swizzle *ir)
    this->result = src;
 }
 
+static
+void update_address_mask_availability(void)
+{
+   switch (available_address_writemask) {
+      case WRITEMASK_X:
+         available_address_writemask = WRITEMASK_Y;
+         available_address_swizzle = SWIZZLE_Y;
+         break;
+      case WRITEMASK_Y:
+         available_address_writemask = WRITEMASK_Z;
+         available_address_swizzle = SWIZZLE_Z;
+         break;
+      case WRITEMASK_Z:
+         available_address_writemask = WRITEMASK_W;
+         available_address_swizzle = SWIZZLE_W;
+         break;
+      case WRITEMASK_W:
+         available_address_writemask = WRITEMASK_X;
+         available_address_swizzle = SWIZZLE_X;
+         break;
+      default:
+         assert(0);
+   }
+}
+
 void
 glsl_to_tgsi_visitor::handle_dereference(ir_dereference *ir)
 {
@@ -2144,8 +2152,12 @@ glsl_to_tgsi_visitor::handle_dereference(ir_dereference *ir)
                      this->result, st_src_reg_for_type(index_reg.type,element_size),index_reg);
             }
          }
+         address_reg.writemask = available_address_writemask;
+         emit_arl(ir,address_reg,index_reg);
          result.reladdr = ralloc(mem_ctx, st_src_reg);
-         memcpy(result.reladdr, &index_reg, sizeof(index_reg));
+         *(result.reladdr) = st_src_reg(address_reg);
+         result.reladdr->swizzle = available_address_swizzle;
+         update_address_mask_availability();
       }
    }
 
@@ -4314,7 +4326,7 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
       src.Indirect = 1;
       src.IndirectFile = addr.File;
       src.IndirectIndex = addr.Index;
-      src.IndirectSwizzle = addr.SwizzleX;
+      src.IndirectSwizzle = GET_SWZ(src_reg->reladdr->swizzle,0);
       
       if (src_reg->file != PROGRAM_INPUT &&
           src_reg->file != PROGRAM_OUTPUT) {
-- 
1.7.7



More information about the mesa-dev mailing list