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

Vincent Lejeune vljn at ovi.com
Fri Dec 30 14:12:13 PST 2011


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

v2: fix glsl-vs-array piglit test

v3: fix fs-temp-array-mat2-index-col-rd piglit test
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |   64 +++++++++++++++++-----------
 1 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 2bfa622..28b8c2a 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -483,6 +483,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);
@@ -748,29 +750,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;
@@ -2113,6 +2096,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)
 {
@@ -2131,10 +2139,10 @@ glsl_to_tgsi_visitor::handle_dereference(ir_dereference *ir)
    }
 
    if (secondary_visitor.indirect_address_expression_count > 0) {
+      st_src_reg index_reg;
       for (unsigned i = 0; i < secondary_visitor.indirect_address_expression_count; i++) {
          secondary_visitor.indirect_address_expression[i].expr->accept(this);
          unsigned element_size = secondary_visitor.indirect_address_expression[i].stride;
-         st_src_reg index_reg;
 
          if (i == 0) {
             if (element_size == 1) {
@@ -2157,9 +2165,13 @@ glsl_to_tgsi_visitor::handle_dereference(ir_dereference *ir)
                      this->result, st_src_reg_for_type(index_reg.type,element_size),index_reg);
             }
          }
-         result.reladdr = ralloc(mem_ctx, st_src_reg);
-         memcpy(result.reladdr, &index_reg, sizeof(index_reg));
       }
+      address_reg.writemask = available_address_writemask;
+      emit_arl(ir,address_reg,index_reg);
+      result.reladdr = ralloc(mem_ctx, st_src_reg);
+      *(result.reladdr) = st_src_reg(address_reg);
+      result.reladdr->swizzle = available_address_swizzle;
+      update_address_mask_availability();
    }
 
    this->result = result;
@@ -4294,8 +4306,10 @@ translate_dst(struct st_translate *t,
    if (saturate)
       dst = ureg_saturate(dst);
 
-   if (dst_reg->reladdr != NULL)
+   if (dst_reg->reladdr != NULL) {
       dst = ureg_dst_indirect(dst, ureg_src(t->address[0]));
+      dst.IndirectSwizzle = GET_SWZ(dst_reg->reladdr->swizzle,0);
+   }
 
    return dst;
 }
@@ -4327,7 +4341,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