summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2013-08-17 00:27:43 -0700
committerIan Romanick <ian.d.romanick@intel.com>2013-08-19 16:40:07 -0700
commitd3004acdd15d0fe3a0ac21f9bd7070d22b13a680 (patch)
treed517a10af14b552730b845f586161bcbe1eced93
parent684316512c5570483365d36849250a008b6fcd84 (diff)
glsl: Use alignment of container record for its first field
The first field of a record in a UBO has the aligment of the record itself. Fixes piglit vs-struct-pad, fs-struct-pad, and (with the patch posted to the piglit list that extends the test) layout-std140. NOTE: The bit of strangeness with the version of visit_field without the record_type poitner is because that method is pure virtual in the base class. The original implementation of the class did this to ensure derived classes remembered to implement that flavor. Now they can implement either flavor but not both. I don't know a C++ way to enforce that. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Paul Berry <stereotype441@gmail.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68195 Cc: "9.2 9.1" mesa-stable@lists.freedesktop.org (cherry picked from commit 574e4843e9e26aa6affa31c80ac42f745b68268b)
-rw-r--r--src/glsl/link_uniform_blocks.cpp17
-rw-r--r--src/glsl/link_uniforms.cpp13
2 files changed, 28 insertions, 2 deletions
diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp
index c72d1d8f1d..e475147e51 100644
--- a/src/glsl/link_uniform_blocks.cpp
+++ b/src/glsl/link_uniform_blocks.cpp
@@ -59,6 +59,15 @@ private:
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
{
+ (void) type;
+ (void) name;
+ (void) row_major;
+ assert(!"Should not get here.");
+ }
+
+ virtual void visit_field(const glsl_type *type, const char *name,
+ bool row_major, const glsl_type *record_type)
+ {
assert(this->index < this->num_variables);
gl_uniform_buffer_variable *v = &this->variables[this->index++];
@@ -85,7 +94,9 @@ private:
v->IndexName = v->Name;
}
- unsigned alignment = type->std140_base_alignment(v->RowMajor);
+ const unsigned alignment = record_type
+ ? record_type->std140_base_alignment(v->RowMajor)
+ : type->std140_base_alignment(v->RowMajor);
unsigned size = type->std140_size(v->RowMajor);
this->offset = glsl_align(this->offset, alignment);
@@ -107,6 +118,10 @@ private:
virtual void visit_field(const glsl_struct_field *field)
{
+ /* FINISHME: When support for doubles (dvec4, etc.) is added to the
+ * FINISHME: compiler, this may be incorrect for a structure in a UBO
+ * FINISHME: like struct s { struct { float f } s1; dvec4 v; };.
+ */
this->offset = glsl_align(this->offset,
field->type->std140_base_alignment(false));
}
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index 095895bf27..fa77157f78 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -402,6 +402,15 @@ private:
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
{
+ (void) type;
+ (void) name;
+ (void) row_major;
+ assert(!"Should not get here.");
+ }
+
+ virtual void visit_field(const glsl_type *type, const char *name,
+ bool row_major, const glsl_type *record_type)
+ {
assert(!type->is_record());
assert(!(type->is_array() && type->fields.array->is_record()));
assert(!type->is_interface());
@@ -446,7 +455,9 @@ private:
if (this->ubo_block_index != -1) {
this->uniforms[id].block_index = this->ubo_block_index;
- unsigned alignment = type->std140_base_alignment(ubo_row_major);
+ const unsigned alignment = record_type
+ ? record_type->std140_base_alignment(ubo_row_major)
+ : type->std140_base_alignment(ubo_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(ubo_row_major);