glsl: Allow geometry shader input instance arrays to be unsized.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -908,11 +908,13 @@ class ast_interface_block : public ast_node {
|
||||
public:
|
||||
ast_interface_block(ast_type_qualifier layout,
|
||||
const char *instance_name,
|
||||
bool is_array,
|
||||
ast_expression *array_size)
|
||||
: layout(layout), block_name(NULL), instance_name(instance_name),
|
||||
array_size(array_size)
|
||||
is_array(is_array), array_size(array_size)
|
||||
{
|
||||
/* empty */
|
||||
if (!is_array)
|
||||
assert(array_size == NULL);
|
||||
}
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
@@ -933,13 +935,19 @@ public:
|
||||
exec_list declarations;
|
||||
|
||||
/**
|
||||
* Declared array size of the block instance
|
||||
*
|
||||
* If the block is not declared as an array, this field will be \c NULL.
|
||||
* True if the block is declared as an array
|
||||
*
|
||||
* \note
|
||||
* A block can only be an array if it also has an instance name. If this
|
||||
* field is not \c NULL, ::instance_name must also not be \c NULL.
|
||||
* field is true, ::instance_name must also not be \c NULL.
|
||||
*/
|
||||
bool is_array;
|
||||
|
||||
/**
|
||||
* Declared array size of the block instance
|
||||
*
|
||||
* If the block is not declared as an array or if the block instance array
|
||||
* is unsized, this field will be \c NULL.
|
||||
*/
|
||||
ast_expression *array_size;
|
||||
};
|
||||
|
@@ -4409,7 +4409,34 @@ ast_interface_block::hir(exec_list *instructions,
|
||||
if (this->instance_name) {
|
||||
ir_variable *var;
|
||||
|
||||
if (this->array_size != NULL) {
|
||||
if (this->is_array) {
|
||||
/* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says:
|
||||
*
|
||||
* For uniform blocks declared an array, each individual array
|
||||
* element corresponds to a separate buffer object backing one
|
||||
* instance of the block. As the array size indicates the number
|
||||
* of buffer objects needed, uniform block array declarations
|
||||
* must specify an array size.
|
||||
*
|
||||
* And a few paragraphs later:
|
||||
*
|
||||
* Geometry shader input blocks must be declared as arrays and
|
||||
* follow the array declaration and linking rules for all
|
||||
* geometry shader inputs. All other input and output block
|
||||
* arrays must specify an array size.
|
||||
*
|
||||
* The upshot of this is that the only circumstance where an
|
||||
* interface array size *doesn't* need to be specified is on a
|
||||
* geometry shader input.
|
||||
*/
|
||||
if (this->array_size == NULL &&
|
||||
(state->target != geometry_shader || !this->layout.flags.q.in)) {
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"only geometry shader inputs may be unsized "
|
||||
"instance block arrays");
|
||||
|
||||
}
|
||||
|
||||
const glsl_type *block_array_type =
|
||||
process_array_type(&loc, block_type, this->array_size, state);
|
||||
|
||||
@@ -4429,7 +4456,7 @@ ast_interface_block::hir(exec_list *instructions,
|
||||
/* In order to have an array size, the block must also be declared with
|
||||
* an instane name.
|
||||
*/
|
||||
assert(this->array_size == NULL);
|
||||
assert(!this->is_array);
|
||||
|
||||
for (unsigned i = 0; i < num_variables; i++) {
|
||||
ir_variable *var =
|
||||
|
@@ -2243,25 +2243,22 @@ instance_name_opt:
|
||||
/* empty */
|
||||
{
|
||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||
NULL, NULL);
|
||||
NULL, false, NULL);
|
||||
}
|
||||
| NEW_IDENTIFIER
|
||||
{
|
||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||
$1, NULL);
|
||||
$1, false, NULL);
|
||||
}
|
||||
| NEW_IDENTIFIER '[' constant_expression ']'
|
||||
{
|
||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||
$1, $3);
|
||||
$1, true, $3);
|
||||
}
|
||||
| NEW_IDENTIFIER '[' ']'
|
||||
{
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"instance block arrays must be explicitly sized");
|
||||
|
||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||
$1, NULL);
|
||||
$1, true, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
|
Reference in New Issue
Block a user