aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/link_uniforms.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/link_uniforms.cpp')
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp46
1 files changed, 39 insertions, 7 deletions
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index de2f6c9ac..799c74bb9 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -169,6 +169,9 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
if (record_type == NULL && t->is_record())
record_type = t;
+ if (t->is_record())
+ this->enter_record(t, *name, row_major);
+
for (unsigned i = 0; i < t->length; i++) {
const char *field = t->fields.structure[i].name;
size_t new_length = name_length;
@@ -208,6 +211,11 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
*/
record_type = NULL;
}
+
+ if (t->is_record()) {
+ (*name)[name_length] = '\0';
+ this->leave_record(t, *name, row_major);
+ }
} else if (t->is_array() && (t->fields.array->is_record()
|| t->fields.array->is_interface())) {
if (record_type == NULL && t->fields.array->is_record())
@@ -249,6 +257,16 @@ program_resource_visitor::visit_field(const glsl_struct_field *field)
/* empty */
}
+void
+program_resource_visitor::enter_record(const glsl_type *, const char *, bool)
+{
+}
+
+void
+program_resource_visitor::leave_record(const glsl_type *, const char *, bool)
+{
+}
+
namespace {
/**
@@ -526,6 +544,20 @@ private:
assert(!"Should not get here.");
}
+ virtual void enter_record(const glsl_type *type, const char *name,
+ bool row_major) {
+ assert(type->is_record());
+ this->ubo_byte_offset = glsl_align(
+ this->ubo_byte_offset, type->std140_base_alignment(row_major));
+ }
+
+ virtual void leave_record(const glsl_type *type, const char *name,
+ bool row_major) {
+ assert(type->is_record());
+ this->ubo_byte_offset = glsl_align(
+ this->ubo_byte_offset, type->std140_base_alignment(row_major));
+ }
+
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major, const glsl_type *record_type,
bool last_field)
@@ -590,16 +622,11 @@ private:
if (this->ubo_block_index != -1) {
this->uniforms[id].block_index = this->ubo_block_index;
- const unsigned alignment = record_type
- ? record_type->std140_base_alignment(row_major)
- : type->std140_base_alignment(row_major);
+ const unsigned alignment = type->std140_base_alignment(row_major);
this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
this->uniforms[id].offset = this->ubo_byte_offset;
this->ubo_byte_offset += type->std140_size(row_major);
- if (last_field)
- this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, 16);
-
if (type->is_array()) {
this->uniforms[id].array_stride =
glsl_align(type->fields.array->std140_size(row_major), 16);
@@ -608,7 +635,12 @@ private:
}
if (type->without_array()->is_matrix()) {
- this->uniforms[id].matrix_stride = 16;
+ const glsl_type *matrix = type->without_array();
+ const unsigned N = matrix->base_type == GLSL_TYPE_DOUBLE ? 8 : 4;
+ const unsigned items = row_major ? matrix->matrix_columns : matrix->vector_elements;
+
+ assert(items <= 4);
+ this->uniforms[id].matrix_stride = glsl_align(items * N, 16);
this->uniforms[id].row_major = row_major;
} else {
this->uniforms[id].matrix_stride = 0;