<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>