summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-03-22 11:26:34 -0700
committerPaul Berry <[email protected]>2013-04-11 09:25:26 -0700
commitdefdb310b76ad30c192a087292e86377f4ea0d83 (patch)
treebed83bbbf720fc4ed3e050f641c1eb80d078e199 /src/mesa
parent444fce6398556118629ef01204a7d8ff7af0bea3 (diff)
i965/vs: Generalize computation of array strides in preparation for GS.
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 <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp19
2 files changed, 16 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 27498590ec2..1f6c5635db2 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -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
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index b9d1543c975..b46f5894d63 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -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) {