linker: Add padding after the last field of a structure
This causes the thing following the structure to be vec4-aligned. Fixes gles3conform failures in: ES3-CTS.shaders.uniform_block.random.nested_structs.2 ES3-CTS.shaders.uniform_block.random.all_shared_buffer.5 Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
@@ -934,14 +934,20 @@ glsl_type::std140_size(bool row_major) const
|
|||||||
*/
|
*/
|
||||||
if (this->is_record()) {
|
if (this->is_record()) {
|
||||||
unsigned size = 0;
|
unsigned size = 0;
|
||||||
|
unsigned max_align = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < this->length; i++) {
|
for (unsigned i = 0; i < this->length; i++) {
|
||||||
const struct glsl_type *field_type = this->fields.structure[i].type;
|
const struct glsl_type *field_type = this->fields.structure[i].type;
|
||||||
unsigned align = field_type->std140_base_alignment(row_major);
|
unsigned align = field_type->std140_base_alignment(row_major);
|
||||||
size = glsl_align(size, align);
|
size = glsl_align(size, align);
|
||||||
size += field_type->std140_size(row_major);
|
size += field_type->std140_size(row_major);
|
||||||
|
|
||||||
|
max_align = MAX2(align, max_align);
|
||||||
|
|
||||||
|
if (field_type->is_record() && (i + 1 < this->length))
|
||||||
|
size = glsl_align(size, 16);
|
||||||
}
|
}
|
||||||
size = glsl_align(size,
|
size = glsl_align(size, max_align);
|
||||||
this->fields.structure[0].type->std140_base_alignment(row_major));
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -104,7 +104,20 @@ private:
|
|||||||
|
|
||||||
this->offset = glsl_align(this->offset, alignment);
|
this->offset = glsl_align(this->offset, alignment);
|
||||||
v->Offset = this->offset;
|
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;
|
this->offset += size;
|
||||||
|
if (last_field)
|
||||||
|
this->offset = glsl_align(this->offset, 16);
|
||||||
|
|
||||||
/* From the GL_ARB_uniform_buffer_object spec:
|
/* From the GL_ARB_uniform_buffer_object spec:
|
||||||
*
|
*
|
||||||
|
@@ -513,7 +513,7 @@ private:
|
|||||||
|
|
||||||
virtual void visit_field(const glsl_type *type, const char *name,
|
virtual void visit_field(const glsl_type *type, const char *name,
|
||||||
bool row_major, const glsl_type *record_type,
|
bool row_major, const glsl_type *record_type,
|
||||||
bool /* last_field */)
|
bool last_field)
|
||||||
{
|
{
|
||||||
assert(!type->without_array()->is_record());
|
assert(!type->without_array()->is_record());
|
||||||
assert(!type->without_array()->is_interface());
|
assert(!type->without_array()->is_interface());
|
||||||
@@ -582,6 +582,9 @@ private:
|
|||||||
this->uniforms[id].offset = this->ubo_byte_offset;
|
this->uniforms[id].offset = this->ubo_byte_offset;
|
||||||
this->ubo_byte_offset += type->std140_size(ubo_row_major);
|
this->ubo_byte_offset += type->std140_size(ubo_row_major);
|
||||||
|
|
||||||
|
if (last_field)
|
||||||
|
this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, 16);
|
||||||
|
|
||||||
if (type->is_array()) {
|
if (type->is_array()) {
|
||||||
this->uniforms[id].array_stride =
|
this->uniforms[id].array_stride =
|
||||||
glsl_align(type->fields.array->std140_size(ubo_row_major), 16);
|
glsl_align(type->fields.array->std140_size(ubo_row_major), 16);
|
||||||
|
Reference in New Issue
Block a user