#include "linker.h"
#include "ir_uniform.h"
#include "link_uniform_block_active_visitor.h"
-#include "main/hash_table.h"
+#include "util/hash_table.h"
#include "program.h"
namespace {
}
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)
{
assert(this->index < this->num_variables);
v->Name = ralloc_strdup(mem_ctx, name);
v->Type = type;
- v->RowMajor = row_major;
+ v->RowMajor = type->without_array()->is_matrix() && row_major;
if (this->is_array_instance) {
v->IndexName = ralloc_strdup(mem_ctx, name);
unsigned len = strlen(close_bracket + 1) + 1;
memmove(open_bracket, close_bracket + 1, len);
- } else {
+ } else {
v->IndexName = v->Name;
}
const unsigned alignment = record_type
- ? record_type->std140_base_alignment(v->RowMajor)
- : type->std140_base_alignment(v->RowMajor);
+ ? 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);
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:
*
* the hash is organized by block-name.
*/
struct hash_table *block_hash =
- _mesa_hash_table_create(mem_ctx, _mesa_key_string_equal);
+ _mesa_hash_table_create(mem_ctx, _mesa_key_hash_string,
+ _mesa_key_string_equal);
if (block_hash == NULL) {
_mesa_error_no_memory(__func__);