i965: Fix intel_miptree_map() signature to be more 64-bit safe
[mesa.git] / src / glsl / link_uniform_blocks.cpp
index 53a18c934648b2ab6b0ddf28b26b5ce8488050bd..f5fc5022e1883f2b116733cb84def27e9493161d 100644 (file)
@@ -26,7 +26,7 @@
 #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 {
@@ -68,7 +68,8 @@ private:
    }
 
    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);
 
@@ -76,7 +77,7 @@ private:
 
       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);
@@ -92,18 +93,31 @@ private:
          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:
        *
@@ -168,7 +182,8 @@ link_uniform_blocks(void *mem_ctx,
     * 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__);