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:
@@ -907,12 +907,14 @@ public:
|
|||||||
class ast_interface_block : public ast_node {
|
class ast_interface_block : public ast_node {
|
||||||
public:
|
public:
|
||||||
ast_interface_block(ast_type_qualifier layout,
|
ast_interface_block(ast_type_qualifier layout,
|
||||||
const char *instance_name,
|
const char *instance_name,
|
||||||
ast_expression *array_size)
|
bool is_array,
|
||||||
|
ast_expression *array_size)
|
||||||
: layout(layout), block_name(NULL), instance_name(instance_name),
|
: 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,
|
virtual ir_rvalue *hir(exec_list *instructions,
|
||||||
@@ -933,13 +935,19 @@ public:
|
|||||||
exec_list declarations;
|
exec_list declarations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declared array size of the block instance
|
* True if the block is declared as an array
|
||||||
*
|
|
||||||
* If the block is not declared as an array, this field will be \c NULL.
|
|
||||||
*
|
*
|
||||||
* \note
|
* \note
|
||||||
* A block can only be an array if it also has an instance name. If this
|
* 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;
|
ast_expression *array_size;
|
||||||
};
|
};
|
||||||
|
@@ -4409,7 +4409,34 @@ ast_interface_block::hir(exec_list *instructions,
|
|||||||
if (this->instance_name) {
|
if (this->instance_name) {
|
||||||
ir_variable *var;
|
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 =
|
const glsl_type *block_array_type =
|
||||||
process_array_type(&loc, block_type, this->array_size, state);
|
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
|
/* In order to have an array size, the block must also be declared with
|
||||||
* an instane name.
|
* an instane name.
|
||||||
*/
|
*/
|
||||||
assert(this->array_size == NULL);
|
assert(!this->is_array);
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_variables; i++) {
|
for (unsigned i = 0; i < num_variables; i++) {
|
||||||
ir_variable *var =
|
ir_variable *var =
|
||||||
|
@@ -2243,25 +2243,22 @@ instance_name_opt:
|
|||||||
/* empty */
|
/* empty */
|
||||||
{
|
{
|
||||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||||
NULL, NULL);
|
NULL, false, NULL);
|
||||||
}
|
}
|
||||||
| NEW_IDENTIFIER
|
| NEW_IDENTIFIER
|
||||||
{
|
{
|
||||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||||
$1, NULL);
|
$1, false, NULL);
|
||||||
}
|
}
|
||||||
| NEW_IDENTIFIER '[' constant_expression ']'
|
| NEW_IDENTIFIER '[' constant_expression ']'
|
||||||
{
|
{
|
||||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||||
$1, $3);
|
$1, true, $3);
|
||||||
}
|
}
|
||||||
| NEW_IDENTIFIER '[' ']'
|
| NEW_IDENTIFIER '[' ']'
|
||||||
{
|
{
|
||||||
_mesa_glsl_error(& @1, state,
|
|
||||||
"instance block arrays must be explicitly sized");
|
|
||||||
|
|
||||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||||
$1, NULL);
|
$1, true, NULL);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user