summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2010-09-01 15:37:13 -0700
committerKenneth Graunke <kenneth@whitecape.org>2010-09-01 18:57:51 -0700
commit54b35e673596d767a13f06f4d7ec1089e18fd46e (patch)
treecee9e096253e85d6dbe658b2befed4eed4b988ac
parent1f7c7df40f830e164f96df4468a2b4fa365c4b84 (diff)
glsl: Add proper handling for constant matrix-from-matrix constructors.
Fixes piglit test case constructor-21.vert and changes constructor-22.vert to give the correct output.
-rw-r--r--src/glsl/ir.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index aee44a77c9..68ad512bf5 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -450,6 +450,31 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
return;
}
+ if (type->is_matrix() && value->type->is_matrix()) {
+ assert(value->next->is_tail_sentinel());
+
+ /* From section 5.4.2 of the GLSL 1.20 spec:
+ * "If a matrix is constructed from a matrix, then each component
+ * (column i, row j) in the result that has a corresponding component
+ * (column i, row j) in the argument will be initialized from there."
+ */
+ unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
+ unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
+ for (unsigned i = 0; i < cols; i++) {
+ for (unsigned j = 0; j < rows; j++) {
+ const unsigned src = i * value->type->vector_elements + j;
+ const unsigned dst = i * type->vector_elements + j;
+ this->value.f[dst] = value->value.f[src];
+ }
+ }
+
+ /* "All other components will be initialized to the identity matrix." */
+ for (unsigned i = cols; i < type->matrix_columns; i++)
+ this->value.f[i * type->vector_elements + i] = 1.0;
+
+ return;
+ }
+
/* Use each component from each entry in the value_list to initialize one
* component of the constant being constructed.
*/