<div dir="ltr">On 22 January 2013 00:52, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>><br>
<br>
If the block has an instance name, add the instance name to the symbol<br>
table instead of the individual fields.<br>
<br>
Fixes the piglit test interface-name-access-without-interface-name.vert<br>
for real.<br>
<br>
Signed-off-by: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>><br>
---<br>
 src/glsl/ast_to_hir.cpp | 167 ++++++++++++++++++++++++++++++++++--------------<br>
 1 file changed, 118 insertions(+), 49 deletions(-)<br>
<br>
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp<br>
index 575dd84..a740a3c 100644<br>
--- a/src/glsl/ast_to_hir.cpp<br>
+++ b/src/glsl/ast_to_hir.cpp<br>
@@ -4020,7 +4020,9 @@ ast_process_structure_or_interface_block(exec_list *instructions,<br>
                                         struct _mesa_glsl_parse_state *state,<br>
                                         exec_list *declarations,<br>
                                         YYLTYPE &loc,<br>
-                                        glsl_struct_field **fields_ret)<br>
+                                        glsl_struct_field **fields_ret,<br>
+                                         bool is_interface,<br>
+                                         bool block_row_major)<br>
 {<br>
    unsigned decl_count = 0;<br>
<br>
@@ -4062,7 +4064,32 @@ ast_process_structure_or_interface_block(exec_list *instructions,<br>
<br>
       foreach_list_typed (ast_declaration, decl, link,<br>
                          &decl_list->declarations) {<br>
-        const struct glsl_type *field_type = decl_type;<br>
+         /* From the GL_ARB_uniform_buffer_object spec:<br>
+          *<br>
+          *     "Sampler types are not allowed inside of uniform<br>
+          *      blocks. All other types, arrays, and structures<br>
+          *      allowed for uniforms are allowed within a uniform<br>
+          *      block."<br>
+          */<br>
+         const struct glsl_type *field_type = decl_type;<br>
+<br>
+         if (is_interface && field_type->contains_sampler()) {<br>
+            YYLTYPE loc = decl_list->get_location();<br>
+            _mesa_glsl_error(&loc, state,<br>
+                             "Uniform in non-default uniform block contains sampler\n");<br>
+         }<br>
+<br>
+         const struct ast_type_qualifier *const qual =<br>
+            & decl_list->type->qualifier;<br>
+         if (qual->flags.q.std140 ||<br>
+             qual->flags.q.packed ||<br>
+             qual->flags.q.shared) {<br>
+            _mesa_glsl_error(&loc, state,<br>
+                             "uniform block layout qualifiers std140, packed, and "<br>
+                             "shared can only be applied to uniform blocks, not "<br>
+                             "members");<br>
+         }<br>
+<br>
         if (decl->is_array) {<br>
            field_type = process_array_type(&loc, decl_type, decl->array_size,<br>
                                            state);<br>
@@ -4070,6 +4097,26 @@ ast_process_structure_or_interface_block(exec_list *instructions,<br>
         fields[i].type = (field_type != NULL)<br>
            ? field_type : glsl_type::error_type;<br>
         fields[i].name = decl->identifier;<br>
+<br>
+         if (qual->flags.q.row_major || qual->flags.q.column_major) {<br>
+            if (!field_type->is_matrix() && !field_type->is_record()) {<br>
+               _mesa_glsl_error(&loc, state,<br>
+                                "uniform block layout qualifiers row_major and "<br>
+                                "column_major can only be applied to matrix and "<br>
+                                "structure types");<br>
+            } else<br>
+               validate_matrix_layout_for_type(state, &loc, field_type);<br>
+         }<br>
+<br>
+         if (field_type->is_matrix() ||<br>
+             (field_type->is_array() && field_type->fields.array->is_matrix())) {<br>
+            fields[i].row_major = block_row_major;<br>
+            if (qual->flags.q.row_major)<br>
+               fields[i].row_major = true;<br>
+            else if (qual->flags.q.column_major)<br>
+               fields[i].row_major = false;<br>
+         }<br>
+<br>
         i++;<br>
       }<br>
    }<br>
@@ -4092,7 +4139,9 @@ ast_struct_specifier::hir(exec_list *instructions,<br>
                                               state,<br>
                                               &this->declarations,<br>
                                               loc,<br>
-                                              &fields);<br>
+                                              &fields,<br>
+                                               false,<br>
+                                               false);<br>
<br>
    const glsl_type *t =<br>
       glsl_type::get_record_instance(fields, decl_count, this->name);<br>
@@ -4138,6 +4187,8 @@ ir_rvalue *<br>
 ast_uniform_block::hir(exec_list *instructions,<br>
                       struct _mesa_glsl_parse_state *state)<br>
 {<br>
+   YYLTYPE loc = this->get_location();<br>
+<br>
    /* The ast_uniform_block has a list of ast_declarator_lists.  We<br>
     * need to turn those into ir_variables with an association<br>
     * with this uniform block.<br>
@@ -4161,60 +4212,78 @@ ast_uniform_block::hir(exec_list *instructions,<br>
       ubo->_Packing = ubo_packing_std140;<br>
    }<br>
<br>
-   unsigned int num_variables = 0;<br>
-   foreach_list_typed(ast_declarator_list, decl_list, link, &declarations) {<br>
-      foreach_list_const(node, &decl_list->declarations) {<br>
-        num_variables++;<br>
+   bool block_row_major = this->layout.flags.q.row_major;<br>
+   exec_list declared_variables;<br>
+   glsl_struct_field *fields;<br>
+   unsigned int num_variables =<br>
+      ast_process_structure_or_interface_block(&declared_variables,<br>
+                                               state,<br>
+                                               &this->declarations,<br>
+                                               loc,<br>
+                                               &fields,<br>
+                                               true,<br>
+                                               block_row_major);<br>
+<br>
+   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140)<br>
+                 == unsigned(ubo_packing_std140));<br>
+   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_SHARED)<br>
+                 == unsigned(ubo_packing_shared));<br>
+   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_PACKED)<br>
+                 == unsigned(ubo_packing_packed));<br>
+<br>
+   const glsl_type *block_type =<br>
+      glsl_type::get_interface_instance(fields,<br>
+                                        num_variables,<br>
+                                        (enum glsl_interface_packing) ubo->_Packing,<br>
+                                        this->block_name);<br>
+<br>
+   /* Since interface blocks cannot contain structure definitions, it should<br>
+    * be impossible for the block to generate any instructions.<br>
+    */<br>
+   assert(declared_variables.is_empty());<br></blockquote><div><br></div><div>I'm confused.  Even if an interface block contained a structure definition, how would that generate instructions?  I would have thought the reason the block wouldn't generate any instructions is because interface blocks can't contain statements.<br>
<br></div><div>Other than that confusion, the patch looks good.<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   /* Page 39 (page 45 of the PDF) of section 4.3.7 in the GLSL ES 3.00 spec<br>
+    * says:<br>
+    *<br>
+    *     "If an instance name (instance-name) is used, then it puts all the<br>
+    *     members inside a scope within its own name space, accessed with the<br>
+    *     field selector ( . ) operator (analogously to structures)."<br>
+    */<br>
+   if (this->instance_name) {<br>
+      ir_variable *var = new(state) ir_variable(block_type,<br>
+                                                this->instance_name,<br>
+                                                ir_var_uniform);<br>
+<br>
+      state->symbols->add_variable(var);<br>
+      instructions->push_tail(var);<br>
+   } else {<br>
+      for (unsigned i = 0; i < num_variables; i++) {<br>
+         ir_variable *var =<br>
+            new(state) ir_variable(fields[i].type,<br>
+                                   ralloc_strdup(state, fields[i].name),<br>
+                                   ir_var_uniform);<br>
+         var->uniform_block = ubo - state->uniform_blocks;<br>
+<br>
+         state->symbols->add_variable(var);<br>
+         instructions->push_tail(var);<br>
       }<br>
    }<br>
<br>
-   bool block_row_major = this->layout.flags.q.row_major;<br>
-<br>
+   /* FINISHME: Eventually the rest of this code needs to be moved into the<br>
+    * FINISHME: linker.<br>
+    */<br>
    ubo->Uniforms = rzalloc_array(state->uniform_blocks,<br>
                                 struct gl_uniform_buffer_variable,<br>
                                 num_variables);<br>
<br>
-   foreach_list_typed(ast_declarator_list, decl_list, link, &declarations) {<br>
-      exec_list declared_variables;<br>
-<br>
-      decl_list->hir(&declared_variables, state);<br>
-<br>
-      foreach_list_const(node, &declared_variables) {<br>
-        ir_variable *var = (ir_variable *)node;<br>
-<br>
-        struct gl_uniform_buffer_variable *ubo_var =<br>
-           &ubo->Uniforms[ubo->NumUniforms++];<br>
-<br>
-        var->uniform_block = ubo - state->uniform_blocks;<br>
-<br>
-        ubo_var->Name = ralloc_strdup(state->uniform_blocks, var->name);<br>
-        ubo_var->Type = var->type;<br>
-        ubo_var->Offset = 0; /* Assigned at link time. */<br>
-<br>
-        if (var->type->is_matrix() ||<br>
-            (var->type->is_array() && var->type->fields.array->is_matrix())) {<br>
-           ubo_var->RowMajor = block_row_major;<br>
-           if (decl_list->type->qualifier.flags.q.row_major)<br>
-              ubo_var->RowMajor = true;<br>
-           else if (decl_list->type->qualifier.flags.q.column_major)<br>
-              ubo_var->RowMajor = false;<br>
-        }<br>
-<br>
-        /* From the GL_ARB_uniform_buffer_object spec:<br>
-         *<br>
-         *     "Sampler types are not allowed inside of uniform<br>
-         *      blocks. All other types, arrays, and structures<br>
-         *      allowed for uniforms are allowed within a uniform<br>
-         *      block."<br>
-         */<br>
-        if (var->type->contains_sampler()) {<br>
-           YYLTYPE loc = decl_list->get_location();<br>
-           _mesa_glsl_error(&loc, state,<br>
-                            "Uniform in non-default uniform block contains sampler\n");<br>
-        }<br>
-      }<br>
+   for (unsigned i = 0; i < num_variables; i++) {<br>
+      struct gl_uniform_buffer_variable *ubo_var =<br>
+         &ubo->Uniforms[ubo->NumUniforms++];<br>
<br>
-      instructions->append_list(&declared_variables);<br>
+      ubo_var->Name = ralloc_strdup(state->uniform_blocks, fields[i].name);<br>
+      ubo_var->Type = fields[i].type;<br>
+      ubo_var->Offset = 0; /* Assigned at link time. */<br>
+      ubo_var->RowMajor = fields[i].row_major;<br>
    }<br>
<br>
    return NULL;<br>
<span><font color="#888888">--<br>
1.7.11.7<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>