summaryrefslogtreecommitdiffstats
path: root/src/glsl/link_uniform_blocks.cpp
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-02-10 03:02:09 -0500
committerIlia Mirkin <[email protected]>2015-02-19 00:28:34 -0500
commit53bf7c8fd2e11a6c64d6ff3a98b56d64d2242505 (patch)
tree7214d2697606da847ffbaa0ba6878c125efdd1dd /src/glsl/link_uniform_blocks.cpp
parent1ec715ce8b126da3cfe3b383054f9a176960c218 (diff)
glsl: fix uniform linking logic in the presence of structs
Add a enter/leave record callback so that the offset may be aligned to the proper value. Otherwise only leaf fields are called, and the first field needs to be aligned to the outer struct's base alignment while the last field needs to be aligned to the inner struct's base alignment. This removes most usage of the last field/record type values passed into visit_field. Signed-off-by: Ilia Mirkin <[email protected]> Reviewed-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/glsl/link_uniform_blocks.cpp')
-rw-r--r--src/glsl/link_uniform_blocks.cpp45
1 files changed, 20 insertions, 25 deletions
diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp
index f5fc5022e18..1c175ec8bdb 100644
--- a/src/glsl/link_uniform_blocks.cpp
+++ b/src/glsl/link_uniform_blocks.cpp
@@ -67,6 +67,25 @@ private:
assert(!"Should not get here.");
}
+ virtual void enter_record(const glsl_type *type, const char *name,
+ bool row_major) {
+ this->offset = glsl_align(
+ this->offset, type->std140_base_alignment(row_major));
+ }
+
+ virtual void leave_record(const glsl_type *type, const char *name,
+ bool row_major) {
+ /* If this is the last field of a structure, apply rule #9. The
+ * GL_ARB_uniform_buffer_object spec says:
+ *
+ * "The structure may have padding at the end; the base offset of
+ * the member following the sub-structure is rounded up to the next
+ * multiple of the base alignment of the structure."
+ */
+ this->offset = glsl_align(
+ this->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)
@@ -97,27 +116,13 @@ private:
v->IndexName = v->Name;
}
- const unsigned alignment = record_type
- ? record_type->std140_base_alignment(v->RowMajor)
- : type->std140_base_alignment(v->RowMajor);
+ const unsigned alignment = type->std140_base_alignment(v->RowMajor);
unsigned size = type->std140_size(v->RowMajor);
this->offset = glsl_align(this->offset, alignment);
v->Offset = this->offset;
- /* If this is the last field of a structure, apply rule #9. The
- * GL_ARB_uniform_buffer_object spec says:
- *
- * "The structure may have padding at the end; the base offset of
- * the member following the sub-structure is rounded up to the next
- * multiple of the base alignment of the structure."
- *
- * last_field won't be set if this is the last field of a UBO that is
- * not a named instance.
- */
this->offset += size;
- if (last_field)
- this->offset = glsl_align(this->offset, 16);
/* From the GL_ARB_uniform_buffer_object spec:
*
@@ -131,16 +136,6 @@ private:
*/
this->buffer_size = glsl_align(this->offset, 16);
}
-
- 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));
- }
};
class count_block_size : public program_resource_visitor {