i965/vs: Track the variable index of array accesses.
authorEric Anholt <eric@anholt.net>
Sun, 7 Aug 2011 17:59:39 +0000 (10:59 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 16 Aug 2011 20:04:42 +0000 (13:04 -0700)
This isn't used currently, as we lower all array accesses.

src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 3e457fc61aa5f774a4bc5b1fe097152dd508c24b..bb40c71e4c9d8054364cf3b35db564c984707b4d 100644 (file)
@@ -169,6 +169,8 @@ public:
    GLuint swizzle; /**< SWIZZLE_XYZW swizzles from Mesa. */
    bool negate;
    bool abs;
+
+   src_reg *reladdr;
 };
 
 class dst_reg : public reg
@@ -219,6 +221,8 @@ public:
    explicit dst_reg(src_reg reg);
 
    int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
+
+   src_reg *reladdr;
 };
 
 class vec4_instruction : public exec_node {
index f90025c8e7ee97a7cb9b279871ddfc9547d097ab..8bd048ff4596063758e0072c50b9aa4c5eafd662 100644 (file)
@@ -37,6 +37,7 @@ src_reg::src_reg(dst_reg reg)
    this->reg = reg.reg;
    this->reg_offset = reg.reg_offset;
    this->type = reg.type;
+   this->reladdr = reg.reladdr;
 
    int swizzles[4];
    int next_chan = 0;
@@ -66,6 +67,7 @@ dst_reg::dst_reg(src_reg reg)
    this->reg_offset = reg.reg_offset;
    this->type = reg.type;
    this->writemask = WRITEMASK_XYZW;
+   this->reladdr = reg.reladdr;
 }
 
 vec4_instruction *
@@ -1186,7 +1188,6 @@ vec4_visitor::visit(ir_dereference_array *ir)
    if (constant_index) {
       src.reg_offset += constant_index->value.i[0] * element_size;
    } else {
-#if 0 /* Variable array index */
       /* Variable index array dereference.  It eats the "vec4" of the
        * base of the array and an index that offsets the Mesa register
        * index.
@@ -1198,15 +1199,22 @@ vec4_visitor::visit(ir_dereference_array *ir)
       if (element_size == 1) {
         index_reg = this->result;
       } else {
-        index_reg = src_reg(this, glsl_type::float_type);
+        index_reg = src_reg(this, glsl_type::int_type);
 
         emit(BRW_OPCODE_MUL, dst_reg(index_reg),
-             this->result, src_reg_for_float(element_size));
+             this->result, src_reg(element_size));
+      }
+
+      if (src.reladdr) {
+        src_reg temp = src_reg(this, glsl_type::int_type);
+
+        emit(BRW_OPCODE_ADD, dst_reg(temp), *src.reladdr, index_reg);
+
+        index_reg = temp;
       }
 
       src.reladdr = ralloc(mem_ctx, src_reg);
       memcpy(src.reladdr, &index_reg, sizeof(index_reg));
-#endif
    }
 
    /* If the type is smaller than a vec4, replicate the last channel out. */