Mesa (9.1): glsl: Use alignment of container record for its first field

Carl Worth cworth at kemper.freedesktop.org
Thu Oct 3 05:00:10 UTC 2013


Module: Mesa
Branch: 9.1
Commit: 895663a24fcf767cebb5ac8666d616c6d1c70d5e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=895663a24fcf767cebb5ac8666d616c6d1c70d5e

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Sat Aug 17 00:27:43 2013 -0700

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 at intel.com>
Reviewed-by: Paul Berry <stereotype441 at gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68195
Cc: "9.2 9.1" mesa-stable at lists.freedesktop.org
(cherry picked from commit 574e4843e9e26aa6affa31c80ac42f745b68268b)

---

 src/glsl/link_uniform_blocks.cpp |   17 ++++++++++++++++-
 src/glsl/link_uniforms.cpp       |   13 ++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp
index c72d1d8..e475147 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 6dda1b9..9ac9c66 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -365,6 +365,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());
@@ -444,7 +453,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);




More information about the mesa-commit mailing list