+
+static void
+copy_uniform_matrix_to_storage(gl_constant_value *storage,
+ GLsizei count, const void *values,
+ const unsigned size_mul, const unsigned offset,
+ const unsigned components,
+ const unsigned vectors, bool transpose,
+ unsigned cols, unsigned rows,
+ enum glsl_base_type basicType)
+{
+ const unsigned elements = components * vectors;
+
+ if (!transpose) {
+ memcpy(storage, values,
+ sizeof(storage[0]) * elements * count * size_mul);
+ } else if (basicType == GLSL_TYPE_FLOAT) {
+ /* Copy and transpose the matrix.
+ */
+ const float *src = (const float *)values;
+ float *dst = &storage->f;
+
+ for (int i = 0; i < count; i++) {
+ for (unsigned r = 0; r < rows; r++) {
+ for (unsigned c = 0; c < cols; c++) {
+ dst[(c * components) + r] = src[c + (r * vectors)];
+ }
+ }
+
+ dst += elements;
+ src += elements;
+ }
+ } else {
+ assert(basicType == GLSL_TYPE_DOUBLE);
+ const double *src = (const double *)values;
+ double *dst = (double *)&storage->f;
+
+ for (int i = 0; i < count; i++) {
+ for (unsigned r = 0; r < rows; r++) {
+ for (unsigned c = 0; c < cols; c++) {
+ dst[(c * components) + r] = src[c + (r * vectors)];
+ }
+ }
+
+ dst += elements;
+ src += elements;
+ }
+ }
+}
+
+