glsl: add matrix layout information to interface block types
authorIago Toral Quiroga <itoral@igalia.com>
Fri, 21 Oct 2016 11:15:41 +0000 (13:15 +0200)
committerIago Toral Quiroga <itoral@igalia.com>
Mon, 24 Oct 2016 13:49:53 +0000 (15:49 +0200)
So far we have been checking that interface block definitions had matching
matrix layouts by comparing the definitions of their fields, however, this
does not cover the case where the interface blocks are defined with
mismatching matrix layouts but don't define any field with a matrix type.
In this case Mesa will not fail to link because none of the fields will
inherit the mismatching layout qualifier.

This patch fixes the problem in the same way we fixed it for packing layout
information: we add the the layout information to the interface type and then
we check it matches during the uniform block linking process.

v2: Fix unit tests so they pass the new parameter to
    glsl_type::get_interface_instance()

Fixes:
dEQP-GLES31.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_3

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com> (v1)
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/builtin_variables.cpp
src/compiler/glsl/link_uniform_blocks.cpp
src/compiler/glsl/linker.cpp
src/compiler/glsl/tests/general_ir_test.cpp
src/compiler/glsl/tests/varyings_test.cpp
src/compiler/glsl_types.cpp
src/compiler/glsl_types.h
src/mesa/main/mtypes.h

index 6e2f253a77da829d0bbb03c5f3cdf7da42bf77b3..adedcbbdf3ccc8920b2796136af1e016f82d4365 100644 (file)
@@ -7516,6 +7516,8 @@ ast_interface_block::hir(exec_list *instructions,
       glsl_type::get_interface_instance(fields,
                                         num_variables,
                                         packing,
+                                        matrix_layout ==
+                                           GLSL_MATRIX_LAYOUT_ROW_MAJOR,
                                         this->block_name);
 
    unsigned component_size = block_type->contains_double() ? 8 : 4;
index 10a87502b41314a58c86d968b9ec7eb3eecf1f63..ca266a4c37ca0ae5c126c01fa92f8b8695b893f6 100644 (file)
@@ -352,6 +352,7 @@ per_vertex_accumulator::construct_interface_instance() const
 {
    return glsl_type::get_interface_instance(this->fields, this->num_fields,
                                             GLSL_INTERFACE_PACKING_STD140,
+                                            false,
                                             "gl_PerVertex");
 }
 
index bb423c55410f5a56c18be557e075eefd15cb1bde..c0bdfa934e0f03b0a704f92d04fda7cad6ff5d4d 100644 (file)
@@ -247,6 +247,7 @@ process_block_array(struct uniform_block_array_elements *ub_array, char **name,
 
       blocks[i].UniformBufferSize = 0;
       blocks[i]._Packing = gl_uniform_block_packing(type->interface_packing);
+      blocks[i]._RowMajor = type->get_interface_row_major();
 
       parcel->process(type, blocks[i].Name);
 
@@ -354,6 +355,7 @@ create_buffer_blocks(void *mem_ctx, struct gl_context *ctx,
             blocks[i].UniformBufferSize = 0;
             blocks[i]._Packing =
                gl_uniform_block_packing(block_type->interface_packing);
+            blocks[i]._RowMajor = block_type->get_interface_row_major();
 
             parcel.process(block_type,
                            b->has_instance_name ? block_type->name : "");
@@ -486,6 +488,9 @@ link_uniform_blocks_are_compatible(const gl_uniform_block *a,
    if (a->_Packing != b->_Packing)
       return false;
 
+   if (a->_RowMajor != b->_RowMajor)
+      return false;
+
    for (unsigned i = 0; i < a->NumUniforms; i++) {
       if (strcmp(a->Uniforms[i].Name, b->Uniforms[i].Name) != 0)
          return false;
index 0b3c195219a48ebf12e20d03e5d3d04154b563a1..af0e29d44f4bb5e594c77b3beb366b5893305f9c 100644 (file)
@@ -1513,9 +1513,10 @@ private:
       }
       glsl_interface_packing packing =
          (glsl_interface_packing) type->interface_packing;
+      bool row_major = (bool) type->interface_row_major;
       const glsl_type *new_ifc_type =
          glsl_type::get_interface_instance(fields, num_fields,
-                                           packing, type->name);
+                                           packing, row_major, type->name);
       delete [] fields;
       return new_ifc_type;
    }
@@ -1543,9 +1544,10 @@ private:
       }
       glsl_interface_packing packing =
          (glsl_interface_packing) ifc_type->interface_packing;
+      bool row_major = (bool) ifc_type->interface_row_major;
       const glsl_type *new_ifc_type =
          glsl_type::get_interface_instance(fields, num_fields, packing,
-                                           ifc_type->name);
+                                           row_major, ifc_type->name);
       delete [] fields;
       for (unsigned i = 0; i < num_fields; i++) {
          if (interface_vars[i] != NULL)
index 217305bf8474ed1bfca367d0ed97847a980c1cc8..57917f337342e6efac07776f2ebeae598bf38947 100644 (file)
@@ -38,6 +38,7 @@ TEST(ir_variable_constructor, interface)
       glsl_type::get_interface_instance(f,
                                         ARRAY_SIZE(f),
                                         GLSL_INTERFACE_PACKING_STD140,
+                                        false,
                                         "simple_interface");
 
    static const char name[] = "named_instance";
@@ -63,6 +64,7 @@ TEST(ir_variable_constructor, interface_array)
       glsl_type::get_interface_instance(f,
                                         ARRAY_SIZE(f),
                                         GLSL_INTERFACE_PACKING_STD140,
+                                        false,
                                         "simple_interface");
 
    const glsl_type *const interface_array =
index 7643e1bbbf917390e0f91e48cd5021e46a29a3be..eb134c9e8f2e2e98f8e7f07e17077088a2a9a10a 100644 (file)
@@ -83,6 +83,7 @@ link_varyings::link_varyings()
       glsl_type::get_interface_instance(f,
                                         ARRAY_SIZE(f),
                                         GLSL_INTERFACE_PACKING_STD140,
+                                        false,
                                         "simple_interface");
 }
 
index 73e3abd329d74b528860ff57ebad4896d5193f8b..55e5285f6c1acd056149a260383ec9f55c104b9b 100644 (file)
@@ -51,7 +51,7 @@ glsl_type::glsl_type(GLenum gl_type,
    gl_type(gl_type),
    base_type(base_type),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampled_type(0), interface_packing(0),
+   sampled_type(0), interface_packing(0), interface_row_major(0),
    vector_elements(vector_elements), matrix_columns(matrix_columns),
    length(0)
 {
@@ -83,7 +83,7 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type,
    base_type(base_type),
    sampler_dimensionality(dim), sampler_shadow(shadow),
    sampler_array(array), sampled_type(type), interface_packing(0),
-   length(0)
+   interface_row_major(0), length(0)
 {
    mtx_lock(&glsl_type::mutex);
 
@@ -108,7 +108,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
    gl_type(0),
    base_type(GLSL_TYPE_STRUCT),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampled_type(0), interface_packing(0),
+   sampled_type(0), interface_packing(0), interface_row_major(0),
    vector_elements(0), matrix_columns(0),
    length(num_fields)
 {
@@ -149,11 +149,13 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
 }
 
 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
-                     enum glsl_interface_packing packing, const char *name) :
+                     enum glsl_interface_packing packing,
+                     bool row_major, const char *name) :
    gl_type(0),
    base_type(GLSL_TYPE_INTERFACE),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
    sampled_type(0), interface_packing((unsigned) packing),
+   interface_row_major((unsigned) row_major),
    vector_elements(0), matrix_columns(0),
    length(num_fields)
 {
@@ -197,7 +199,7 @@ glsl_type::glsl_type(const glsl_type *return_type,
    gl_type(0),
    base_type(GLSL_TYPE_FUNCTION),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampled_type(0), interface_packing(0),
+   sampled_type(0), interface_packing(0), interface_row_major(0),
    vector_elements(0), matrix_columns(0),
    length(num_params)
 {
@@ -229,7 +231,7 @@ glsl_type::glsl_type(const char *subroutine_name) :
    gl_type(0),
    base_type(GLSL_TYPE_SUBROUTINE),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampled_type(0), interface_packing(0),
+   sampled_type(0), interface_packing(0), interface_row_major(0),
    vector_elements(1), matrix_columns(1),
    length(0)
 {
@@ -445,7 +447,7 @@ _mesa_glsl_release_types(void)
 glsl_type::glsl_type(const glsl_type *array, unsigned length) :
    base_type(GLSL_TYPE_ARRAY),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampled_type(0), interface_packing(0),
+   sampled_type(0), interface_packing(0), interface_row_major(0),
    vector_elements(0), matrix_columns(0),
    length(length), name(NULL)
 {
@@ -882,6 +884,9 @@ glsl_type::record_compare(const glsl_type *b, bool match_locations) const
    if (this->interface_packing != b->interface_packing)
       return false;
 
+   if (this->interface_row_major != b->interface_row_major)
+      return false;
+
    /* From the GLSL 4.20 specification (Sec 4.2):
     *
     *     "Structures must have the same name, sequence of type names, and
@@ -1028,9 +1033,10 @@ const glsl_type *
 glsl_type::get_interface_instance(const glsl_struct_field *fields,
                                   unsigned num_fields,
                                   enum glsl_interface_packing packing,
+                                  bool row_major,
                                   const char *block_name)
 {
-   const glsl_type key(fields, num_fields, packing, block_name);
+   const glsl_type key(fields, num_fields, packing, row_major, block_name);
 
    mtx_lock(&glsl_type::mutex);
 
@@ -1044,7 +1050,7 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
    if (entry == NULL) {
       mtx_unlock(&glsl_type::mutex);
       const glsl_type *t = new glsl_type(fields, num_fields,
-                                         packing, block_name);
+                                         packing, row_major, block_name);
       mtx_lock(&glsl_type::mutex);
 
       entry = _mesa_hash_table_insert(interface_types, t, (void *) t);
index b1e2f7a018142ae577b50ec022a4f430dc8fd86f..e5b9f3ba03d2b1f0efcb223588fb257cd34b2691 100644 (file)
@@ -137,6 +137,7 @@ struct glsl_type {
                                * and \c GLSL_TYPE_UINT are valid.
                                */
    unsigned interface_packing:2;
+   unsigned interface_row_major:1;
 
    /* Callers of this ralloc-based new need not call delete. It's
     * easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
@@ -282,6 +283,7 @@ struct glsl_type {
    static const glsl_type *get_interface_instance(const glsl_struct_field *fields,
                                                  unsigned num_fields,
                                                  enum glsl_interface_packing packing,
+                                                 bool row_major,
                                                  const char *block_name);
 
    /**
@@ -770,6 +772,14 @@ struct glsl_type {
       return (enum glsl_interface_packing)interface_packing;
    }
 
+   /**
+    * Check if the type interface is row major
+    */
+   bool get_interface_row_major() const
+   {
+      return (bool) interface_row_major;
+   }
+
 private:
 
    static mtx_t mutex;
@@ -799,7 +809,8 @@ private:
 
    /** Constructor for interface types */
    glsl_type(const glsl_struct_field *fields, unsigned num_fields,
-            enum glsl_interface_packing packing, const char *name);
+            enum glsl_interface_packing packing,
+            bool row_major, const char *name);
 
    /** Constructor for interface types */
    glsl_type(const glsl_type *return_type,
index 88397b93e5789a6da6ec8a06c80478dcdddcbeb6..79dd1c51df7090ab05273b09babdaf54b9682563 100644 (file)
@@ -2577,6 +2577,7 @@ struct gl_uniform_block
     * cross-validating uniform blocks.
     */
    enum gl_uniform_block_packing _Packing;
+   GLboolean _RowMajor;
 };
 
 /**