i965/vs: Generalize computation of array strides in preparation for GS.
authorPaul Berry <stereotype441@gmail.com>
Fri, 22 Mar 2013 18:26:34 +0000 (11:26 -0700)
committerPaul Berry <stereotype441@gmail.com>
Thu, 11 Apr 2013 16:25:26 +0000 (09:25 -0700)
Geometry shader inputs are arrays, but they use an unusual array
layout: instead of all array elements for a given geometry shader
input being stored consecutively, all geometry shader inputs are
interleaved into one giant array.  As a result, the array stride we
use to access geometry shader inputs must be equal to the size of the
input VUE, rather than the size of the array element.

This patch introduces a new virtual function,
vec4_visitor::compute_array_stride(), which will allow geometry shader
compilation to specialize the computation of array stride to account
for the unusual layout of geometry shader input arrays.  It also
renames the local variable that the ir_dereference_array visitor uses
to store the stride, to avoid confusion.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 27498590ec28e5a5315c3d2d6753394476da1fdc..1f6c5635db2c0f2307ec66c8078f60f6f4fa2f0e 100644 (file)
@@ -488,6 +488,7 @@ protected:
    virtual void emit_thread_end() = 0;
    virtual void emit_urb_write_header(int mrf) = 0;
    virtual vec4_instruction *emit_urb_write_opcode(bool complete) = 0;
+   virtual int compute_array_stride(ir_dereference_array *ir);
 };
 
 class vec4_vs_visitor : public vec4_visitor
index b9d1543c975981c20102f0b90fe0d25a6353230b..b46f5894d6333d580f752bb8b71657010c0588e2 100644 (file)
@@ -1692,12 +1692,23 @@ vec4_visitor::visit(ir_dereference_variable *ir)
       this->result.swizzle = swizzle_for_size(type->vector_elements);
 }
 
+
+int
+vec4_visitor::compute_array_stride(ir_dereference_array *ir)
+{
+   /* Under normal circumstances array elements are stored consecutively, so
+    * the stride is equal to the size of the array element.
+    */
+   return type_size(ir->type);
+}
+
+
 void
 vec4_visitor::visit(ir_dereference_array *ir)
 {
    ir_constant *constant_index;
    src_reg src;
-   int element_size = type_size(ir->type);
+   int array_stride = compute_array_stride(ir);
 
    constant_index = ir->array_index->constant_expression_value();
 
@@ -1705,7 +1716,7 @@ vec4_visitor::visit(ir_dereference_array *ir)
    src = this->result;
 
    if (constant_index) {
-      src.reg_offset += constant_index->value.i[0] * element_size;
+      src.reg_offset += constant_index->value.i[0] * array_stride;
    } else {
       /* Variable index array dereference.  It eats the "vec4" of the
        * base of the array and an index that offsets the Mesa register
@@ -1715,12 +1726,12 @@ vec4_visitor::visit(ir_dereference_array *ir)
 
       src_reg index_reg;
 
-      if (element_size == 1) {
+      if (array_stride == 1) {
         index_reg = this->result;
       } else {
         index_reg = src_reg(this, glsl_type::int_type);
 
-        emit(MUL(dst_reg(index_reg), this->result, src_reg(element_size)));
+        emit(MUL(dst_reg(index_reg), this->result, src_reg(array_stride)));
       }
 
       if (src.reladdr) {