#include "ast.h"
#include "glsl_types.h"
#include "program/hash_table.h"
+#include "main/shaderobj.h"
#include "ir.h"
#include "ir_builder.h"
return type_a;
}
+/**
+ * Returns the innermost array index expression in an rvalue tree.
+ * This is the largest indexing level -- if an array of blocks, then
+ * it is the block index rather than an indexing expression for an
+ * array-typed member of an array of blocks.
+ */
+static ir_rvalue *
+find_innermost_array_index(ir_rvalue *rv)
+{
+ ir_dereference_array *last = NULL;
+ while (rv) {
+ if (rv->as_dereference_array()) {
+ last = rv->as_dereference_array();
+ rv = last->array;
+ } else if (rv->as_dereference_record())
+ rv = rv->as_dereference_record()->record;
+ else if (rv->as_swizzle())
+ rv = rv->as_swizzle()->val;
+ else
+ rv = NULL;
+ }
+
+ if (last)
+ return last->array_index;
+
+ return NULL;
+}
+
/**
* Validates that a value can be assigned to a location with a specified type
*
* In addition to being used for assignments, this function is used to
* type-check return values.
*/
-ir_rvalue *
+static ir_rvalue *
validate_assignment(struct _mesa_glsl_parse_state *state,
- YYLTYPE loc, const glsl_type *lhs_type,
+ YYLTYPE loc, ir_rvalue *lhs,
ir_rvalue *rhs, bool is_initializer)
{
/* If there is already some error in the RHS, just return it. Anything
if (rhs->type->is_error())
return rhs;
+ /* In the Tessellation Control Shader:
+ * If a per-vertex output variable is used as an l-value, it is an error
+ * if the expression indicating the vertex number is not the identifier
+ * `gl_InvocationID`.
+ */
+ if (state->stage == MESA_SHADER_TESS_CTRL) {
+ ir_variable *var = lhs->variable_referenced();
+ if (var->data.mode == ir_var_shader_out && !var->data.patch) {
+ ir_rvalue *index = find_innermost_array_index(lhs);
+ ir_variable *index_var = index ? index->variable_referenced() : NULL;
+ if (!index_var || strcmp(index_var->name, "gl_InvocationID") != 0) {
+ _mesa_glsl_error(&loc, state,
+ "Tessellation control shader outputs can only "
+ "be indexed by gl_InvocationID");
+ return NULL;
+ }
+ }
+ }
+
/* If the types are identical, the assignment can trivially proceed.
*/
- if (rhs->type == lhs_type)
+ if (rhs->type == lhs->type)
return rhs;
/* If the array element types are the same and the LHS is unsized,
* Note: Whole-array assignments are not permitted in GLSL 1.10, but this
* is handled by ir_dereference::is_lvalue.
*/
- if (lhs_type->is_unsized_array() && rhs->type->is_array()
- && (lhs_type->fields.array == rhs->type->fields.array)) {
+ if (lhs->type->is_unsized_array() && rhs->type->is_array()
+ && (lhs->type->fields.array == rhs->type->fields.array)) {
if (is_initializer) {
return rhs;
} else {
}
/* Check for implicit conversion in GLSL 1.20 */
- if (apply_implicit_conversion(lhs_type, rhs, state)) {
- if (rhs->type == lhs_type)
+ if (apply_implicit_conversion(lhs->type, rhs, state)) {
+ if (rhs->type == lhs->type)
return rhs;
}
"%s of type %s cannot be assigned to "
"variable of type %s",
is_initializer ? "initializer" : "value",
- rhs->type->name, lhs_type->name);
+ rhs->type->name, lhs->type->name);
return NULL;
}
if (unlikely(lhs_expr->operation == ir_binop_vector_extract)) {
ir_rvalue *new_rhs =
- validate_assignment(state, lhs_loc, lhs->type,
+ validate_assignment(state, lhs_loc, lhs,
rhs, is_initializer);
if (new_rhs == NULL) {
}
ir_rvalue *new_rhs =
- validate_assignment(state, lhs_loc, lhs->type, rhs, is_initializer);
+ validate_assignment(state, lhs_loc, lhs, rhs, is_initializer);
if (new_rhs != NULL) {
rhs = new_rhs;
case GLSL_TYPE_IMAGE:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_SUBROUTINE:
/* I assume a comparison of a struct containing a sampler just
* ignores the sampler present in the type.
*/
static bool
validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
YYLTYPE *loc,
- ir_variable *var,
+ const glsl_type *type,
const ast_type_qualifier *qual)
{
- if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage) {
+ if (!qual->flags.q.uniform && !qual->flags.q.buffer) {
_mesa_glsl_error(loc, state,
"the \"binding\" qualifier only applies to uniforms and "
"shader storage buffer objects");
}
const struct gl_context *const ctx = state->ctx;
- unsigned elements = var->type->is_array() ? var->type->length : 1;
+ unsigned elements = type->is_array() ? type->length : 1;
unsigned max_index = qual->binding + elements - 1;
+ const glsl_type *base_type = type->without_array();
- if (var->type->is_interface()) {
+ if (base_type->is_interface()) {
/* UBOs. From page 60 of the GLSL 4.20 specification:
* "If the binding point for any uniform block instance is less than zero,
* or greater than or equal to the implementation-dependent maximum
*
* The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS.
*/
- if (var->data.mode == ir_var_uniform &&
+ if (qual->flags.q.uniform &&
max_index >= ctx->Const.MaxUniformBufferBindings) {
_mesa_glsl_error(loc, state, "layout(binding = %d) for %d UBOs exceeds "
"the maximum number of UBO binding points (%d)",
ctx->Const.MaxUniformBufferBindings);
return false;
}
+
/* SSBOs. From page 67 of the GLSL 4.30 specification:
* "If the binding point for any uniform or shader storage block instance
* is less than zero, or greater than or equal to the
* N, all elements of the array from binding through binding + N – 1 must
* be within this range."
*/
- if (var->data.mode == ir_var_shader_storage &&
+ if (qual->flags.q.buffer &&
max_index >= ctx->Const.MaxShaderStorageBufferBindings) {
_mesa_glsl_error(loc, state, "layout(binding = %d) for %d SSBOs exceeds "
"the maximum number of SSBO binding points (%d)",
ctx->Const.MaxShaderStorageBufferBindings);
return false;
}
- } else if (var->type->is_sampler() ||
- (var->type->is_array() && var->type->fields.array->is_sampler())) {
+ } else if (base_type->is_sampler()) {
/* Samplers. From page 63 of the GLSL 4.20 specification:
* "If the binding is less than zero, or greater than or equal to the
* implementation-dependent maximum supported number of units, a
return false;
}
- } else if (var->type->contains_atomic()) {
+ } else if (base_type->contains_atomic()) {
assert(ctx->Const.MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS);
if (unsigned(qual->binding) >= ctx->Const.MaxAtomicBufferBindings) {
_mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the "
return false;
}
+ } else if (state->is_version(420, 310) && base_type->is_image()) {
+ assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);
+ if (max_index >= ctx->Const.MaxImageUnits) {
+ _mesa_glsl_error(loc, state, "Image binding %d exceeds the "
+ " maximum number of image units (%d)", max_index,
+ ctx->Const.MaxImageUnits);
+ return false;
+ }
+
} else {
_mesa_glsl_error(loc, state,
"the \"binding\" qualifier only applies to uniform "
- "blocks, samplers, atomic counters, or arrays thereof");
+ "blocks, opaque variables, or arrays thereof");
return false;
}
case MESA_SHADER_TESS_CTRL:
case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY:
- var->data.location = qual->location + VARYING_SLOT_VAR0;
+ if (var->data.patch)
+ var->data.location = qual->location + VARYING_SLOT_PATCH0;
+ else
+ var->data.location = qual->location + VARYING_SLOT_VAR0;
break;
case MESA_SHADER_FRAGMENT:
var->data.image_format = qual->image_format;
} else {
- if (var->data.mode == ir_var_uniform && !qual->flags.q.write_only) {
- _mesa_glsl_error(loc, state, "uniforms not qualified with "
- "`writeonly' must have a format layout "
- "qualifier");
+ if (var->data.mode == ir_var_uniform) {
+ if (state->es_shader) {
+ _mesa_glsl_error(loc, state, "all image uniforms "
+ "must have a format layout qualifier");
+
+ } else if (!qual->flags.q.write_only) {
+ _mesa_glsl_error(loc, state, "image uniforms not qualified with "
+ "`writeonly' must have a format layout "
+ "qualifier");
+ }
}
var->data.image_format = GL_NONE;
}
+
+ /* From page 70 of the GLSL ES 3.1 specification:
+ *
+ * "Except for image variables qualified with the format qualifiers
+ * r32f, r32i, and r32ui, image variables must specify either memory
+ * qualifier readonly or the memory qualifier writeonly."
+ */
+ if (state->es_shader &&
+ var->data.image_format != GL_R32F &&
+ var->data.image_format != GL_R32I &&
+ var->data.image_format != GL_R32UI &&
+ !var->data.image_read_only &&
+ !var->data.image_write_only) {
+ _mesa_glsl_error(loc, state, "image variables of format other than "
+ "r32f, r32i or r32ui must be qualified `readonly' or "
+ "`writeonly'");
+ }
+
} else if (qual->flags.q.read_only ||
qual->flags.q.write_only ||
qual->flags.q.coherent ||
}
}
+ if (qual->flags.q.subroutine && !qual->flags.q.uniform) {
+ _mesa_glsl_error(loc, state,
+ "`subroutine' may only be applied to uniforms, "
+ "subroutine type declarations, or function definitions");
+ }
+
if (qual->flags.q.constant || qual->flags.q.attribute
|| qual->flags.q.uniform
|| (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
}
if (qual->flags.q.explicit_binding &&
- validate_binding_qualifier(state, loc, var, qual)) {
+ validate_binding_qualifier(state, loc, var->type, qual)) {
var->data.explicit_binding = true;
var->data.binding = qual->binding;
}
var->data.depth_layout = ir_depth_layout_none;
if (qual->flags.q.std140 ||
+ qual->flags.q.std430 ||
qual->flags.q.packed ||
qual->flags.q.shared) {
_mesa_glsl_error(loc, state,
- "uniform block layout qualifiers std140, packed, and "
- "shared can only be applied to uniform blocks, not "
+ "uniform and shader storage block layout qualifiers "
+ "std140, std430, packed, and shared can only be "
+ "applied to uniform or shader storage blocks, not "
"members");
}
if (type->qualifier.flags.q.constant
|| type->qualifier.flags.q.uniform) {
ir_rvalue *new_rhs = validate_assignment(state, initializer_loc,
- var->type, rhs, true);
+ lhs, rhs, true);
if (new_rhs != NULL) {
rhs = new_rhs;
validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
&state->tcs_output_size,
- "geometry shader input");
+ "tessellation control shader output");
+}
+
+/**
+ * Do additional processing necessary for tessellation control/evaluation shader
+ * input declarations. This covers both interface block arrays and bare input
+ * variables.
+ */
+static void
+handle_tess_shader_input_decl(struct _mesa_glsl_parse_state *state,
+ YYLTYPE loc, ir_variable *var)
+{
+ if (!var->type->is_array() && !var->data.patch) {
+ _mesa_glsl_error(&loc, state,
+ "per-vertex tessellation shader inputs must be arrays");
+ /* Avoid cascading failures. */
+ return;
+ }
+
+ if (var->data.patch)
+ return;
+
+ /* Unsized arrays are implicitly sized to gl_MaxPatchVertices. */
+ if (var->type->is_unsized_array()) {
+ var->type = glsl_type::get_array_instance(var->type->fields.array,
+ state->Const.MaxPatchVertices);
+ }
}
+
/**
* Do additional processing necessary for geometry shader input declarations
* (this covers both interface blocks arrays and bare input variables).
static bool
precision_qualifier_allowed(const glsl_type *type)
{
- /* Precision qualifiers apply to floating point, integer and sampler
+ /* Precision qualifiers apply to floating point, integer and opaque
* types.
*
* Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says:
return type->is_float()
|| type->is_integer()
|| type->is_record()
- || type->is_sampler();
+ || type->contains_opaque();
}
ir_rvalue *
foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
const struct glsl_type *var_type;
ir_variable *var;
-
+ const char *identifier = decl->identifier;
/* FINISHME: Emit a warning if a variable declaration shadows a
* FINISHME: declaration at a higher scope.
*/
continue;
}
+ if (this->type->qualifier.flags.q.subroutine) {
+ const glsl_type *t;
+ const char *name;
+
+ t = state->symbols->get_type(this->type->specifier->type_name);
+ if (!t)
+ _mesa_glsl_error(& loc, state,
+ "invalid type in declaration of `%s'",
+ decl->identifier);
+ name = ralloc_asprintf(ctx, "%s_%s", _mesa_shader_stage_to_subroutine_prefix(state->stage), decl->identifier);
+
+ identifier = name;
+
+ }
var_type = process_array_type(&loc, decl_type, decl->array_specifier,
state);
- var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
+ var = new(ctx) ir_variable(var_type, identifier, ir_var_auto);
/* The 'varying in' and 'varying out' qualifiers can only be used with
* ARB_geometry_shader4 and EXT_geometry_shader4, which we don't support
*/
if (this->type->qualifier.flags.q.attribute) {
mode = "attribute";
+ } else if (this->type->qualifier.flags.q.subroutine) {
+ mode = "subroutine uniform";
} else if (this->type->qualifier.flags.q.uniform) {
mode = "uniform";
} else if (this->type->qualifier.flags.q.varying) {
}
}
}
+ } else if (state->stage == MESA_SHADER_TESS_CTRL ||
+ state->stage == MESA_SHADER_TESS_EVAL) {
+ handle_tess_shader_input_decl(state, loc, var);
}
} else if (var->data.mode == ir_var_shader_out) {
const glsl_type *check_type = var->type->without_array();
if (state->stage == MESA_SHADER_TESS_CTRL) {
handle_tess_ctrl_shader_output_decl(state, loc, var);
}
+ } else if (var->type->contains_subroutine()) {
+ /* declare subroutine uniforms as hidden */
+ var->data.how_declared = ir_var_hidden;
}
/* Integer fragment inputs must be qualified with 'flat'. In GLSL ES,
_mesa_glsl_error(&loc, state,
"precision qualifiers apply only to floating point"
- ", integer and sampler types");
+ ", integer and opaque types");
}
/* From section 4.1.7 of the GLSL 4.40 spec:
ir_function *f = NULL;
ir_function_signature *sig = NULL;
exec_list hir_parameters;
+ YYLTYPE loc = this->get_location();
const char *const name = identifier;
return_type = glsl_type::error_type;
}
+ /* ARB_shader_subroutine states:
+ * "Subroutine declarations cannot be prototyped. It is an error to prepend
+ * subroutine(...) to a function declaration."
+ */
+ if (this->return_type->qualifier.flags.q.subroutine_def && !is_definition) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "function declaration `%s' cannot have subroutine prepended",
+ name);
+ }
+
/* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
* "No qualifier is allowed on the return type of a function."
*/
f = state->symbols->get_function(name);
if (f == NULL) {
f = new(ctx) ir_function(name);
- if (!state->symbols->add_function(f)) {
- /* This function name shadows a non-function use of the same name. */
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
- "non-function", name);
- return NULL;
+ if (!this->return_type->qualifier.flags.q.subroutine) {
+ if (!state->symbols->add_function(f)) {
+ /* This function name shadows a non-function use of the same name. */
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
+ "non-function", name);
+ return NULL;
+ }
}
-
emit_function(state, f);
}
if (state->es_shader && state->language_version >= 300) {
/* Local shader has no exact candidates; check the built-ins. */
_mesa_glsl_initialize_builtin_functions();
- if (_mesa_glsl_find_builtin_function_by_name(state, name)) {
+ if (_mesa_glsl_find_builtin_function_by_name(name)) {
YYLTYPE loc = this->get_location();
_mesa_glsl_error(& loc, state,
"A shader cannot redefine or overload built-in "
sig->replace_parameters(&hir_parameters);
signature = sig;
+ if (this->return_type->qualifier.flags.q.subroutine_def) {
+ int idx;
+
+ f->num_subroutine_types = this->return_type->qualifier.subroutine_list->declarations.length();
+ f->subroutine_types = ralloc_array(state, const struct glsl_type *,
+ f->num_subroutine_types);
+ idx = 0;
+ foreach_list_typed(ast_declaration, decl, link, &this->return_type->qualifier.subroutine_list->declarations) {
+ const struct glsl_type *type;
+ /* the subroutine type must be already declared */
+ type = state->symbols->get_type(decl->identifier);
+ if (!type) {
+ _mesa_glsl_error(& loc, state, "unknown type '%s' in subroutine function definition", decl->identifier);
+ }
+ f->subroutine_types[idx++] = type;
+ }
+ state->subroutines = (ir_function **)reralloc(state, state->subroutines,
+ ir_function *,
+ state->num_subroutines + 1);
+ state->subroutines[state->num_subroutines] = f;
+ state->num_subroutines++;
+
+ }
+
+ if (this->return_type->qualifier.flags.q.subroutine) {
+ if (!state->symbols->add_type(this->identifier, glsl_type::get_subroutine_instance(this->identifier))) {
+ _mesa_glsl_error(& loc, state, "type '%s' previously defined", this->identifier);
+ return NULL;
+ }
+ state->subroutine_types = (ir_function **)reralloc(state, state->subroutine_types,
+ ir_function *,
+ state->num_subroutine_types + 1);
+ state->subroutine_types[state->num_subroutine_types] = f;
+ state->num_subroutine_types++;
+
+ f->is_subroutine = true;
+ }
+
/* Function declarations (prototypes) do not have r-values.
*/
return NULL;
/* "int" and "float" are valid, but vectors and matrices are not. */
return type->vector_elements == 1 && type->matrix_columns == 1;
case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_ATOMIC_UINT:
return true;
default:
return false;
if (!is_valid_default_precision_type(type)) {
_mesa_glsl_error(&loc, state,
"default precision statements apply only to "
- "float, int, and sampler types");
+ "float, int, and opaque types");
return NULL;
}
}
if (field_type->contains_atomic()) {
- /* FINISHME: Add a spec quotation here once updated spec
- * FINISHME: language is available. See Khronos bug #10903
- * FINISHME: on whether atomic counters are allowed in
- * FINISHME: structures.
+ /* From section 4.1.7.3 of the GLSL 4.40 spec:
+ *
+ * "Members of structures cannot be declared as atomic counter
+ * types."
*/
YYLTYPE loc = decl_list->get_location();
_mesa_glsl_error(&loc, state, "atomic counter in structure, "
const struct ast_type_qualifier *const qual =
& decl_list->type->qualifier;
if (qual->flags.q.std140 ||
+ qual->flags.q.std430 ||
qual->flags.q.packed ||
qual->flags.q.shared) {
_mesa_glsl_error(&loc, state,
"uniform/shader storage block layout qualifiers "
- "std140, packed, and shared can only be applied "
- "to uniform/shader storage blocks, not members");
+ "std140, std430, packed, and shared can only be "
+ "applied to uniform/shader storage blocks, not "
+ "members");
}
if (qual->flags.q.constant) {
bool found;
};
+static bool
+is_unsized_array_last_element(ir_variable *v)
+{
+ const glsl_type *interface_type = v->get_interface_type();
+ int length = interface_type->length;
+
+ assert(v->type->is_unsized_array());
+
+ /* Check if it is the last element of the interface */
+ if (strcmp(interface_type->fields.structure[length-1].name, v->name) == 0)
+ return true;
+ return false;
+}
ir_rvalue *
ast_interface_block::hir(exec_list *instructions,
this->block_name);
}
+ if (!this->layout.flags.q.buffer &&
+ this->layout.flags.q.std430) {
+ _mesa_glsl_error(&loc, state,
+ "std430 storage block layout qualifier is supported "
+ "only for shader storage blocks");
+ }
+
/* The ast_interface_block has a list of ast_declarator_lists. We
* need to turn those into ir_variables with an association
* with this uniform block.
packing = GLSL_INTERFACE_PACKING_SHARED;
} else if (this->layout.flags.q.packed) {
packing = GLSL_INTERFACE_PACKING_PACKED;
+ } else if (this->layout.flags.q.std430) {
+ packing = GLSL_INTERFACE_PACKING_STD430;
} else {
/* The default layout is std140.
*/
if (ir_variable *earlier_gl_Position =
state->symbols->get_variable("gl_Position")) {
earlier_per_vertex = earlier_gl_Position->get_interface_type();
+ } else if (ir_variable *earlier_gl_out =
+ state->symbols->get_variable("gl_out")) {
+ earlier_per_vertex = earlier_gl_out->get_interface_type();
} else {
_mesa_glsl_error(&loc, state,
"redeclaration of gl_PerVertex output not "
"allowed in the %s shader",
_mesa_shader_stage_to_string(state->stage));
}
- if (this->instance_name != NULL) {
- _mesa_glsl_error(&loc, state,
- "gl_PerVertex output may not be redeclared with "
- "an instance name");
+ if (state->stage == MESA_SHADER_TESS_CTRL) {
+ if (this->instance_name == NULL ||
+ strcmp(this->instance_name, "gl_out") != 0 || this->array_specifier == NULL) {
+ _mesa_glsl_error(&loc, state,
+ "gl_PerVertex output must be redeclared as "
+ "gl_out[]");
+ }
+ } else {
+ if (this->instance_name != NULL) {
+ _mesa_glsl_error(&loc, state,
+ "gl_PerVertex output may not be redeclared with "
+ "an instance name");
+ }
}
break;
default:
num_variables,
packing,
this->block_name);
+ if (this->layout.flags.q.explicit_binding)
+ validate_binding_qualifier(state, &loc, block_type, &this->layout);
if (!state->symbols->add_interface(block_type->name, block_type, var_mode)) {
YYLTYPE loc = this->get_location();
if (state->stage == MESA_SHADER_GEOMETRY && this->array_specifier == NULL &&
var_mode == ir_var_shader_in) {
_mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays");
+ } else if ((state->stage == MESA_SHADER_TESS_CTRL ||
+ state->stage == MESA_SHADER_TESS_EVAL) &&
+ this->array_specifier == NULL &&
+ var_mode == ir_var_shader_in) {
+ _mesa_glsl_error(&loc, state, "per-vertex tessellation shader inputs must be arrays");
+ } else if (state->stage == MESA_SHADER_TESS_CTRL &&
+ this->array_specifier == NULL &&
+ var_mode == ir_var_shader_out) {
+ _mesa_glsl_error(&loc, state, "tessellation control shader outputs must be arrays");
}
+
/* Page 39 (page 45 of the PDF) of section 4.3.7 in the GLSL ES 3.00 spec
* says:
*
* geometry shader inputs. All other input and output block
* arrays must specify an array size.
*
+ * The same applies to tessellation shaders.
+ *
* 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.
+ * geometry shader input, tessellation control shader input,
+ * tessellation control shader output, and tessellation evaluation
+ * shader input.
*/
- if (this->array_specifier->is_unsized_array &&
- (state->stage != MESA_SHADER_GEOMETRY || !this->layout.flags.q.in)) {
- _mesa_glsl_error(&loc, state,
- "only geometry shader inputs may be unsized "
- "instance block arrays");
-
+ if (this->array_specifier->is_unsized_array) {
+ bool allow_inputs = state->stage == MESA_SHADER_GEOMETRY ||
+ state->stage == MESA_SHADER_TESS_CTRL ||
+ state->stage == MESA_SHADER_TESS_EVAL;
+ bool allow_outputs = state->stage == MESA_SHADER_TESS_CTRL;
+
+ if (this->layout.flags.q.in) {
+ if (!allow_inputs)
+ _mesa_glsl_error(&loc, state,
+ "unsized input block arrays not allowed in "
+ "%s shader",
+ _mesa_shader_stage_to_string(state->stage));
+ } else if (this->layout.flags.q.out) {
+ if (!allow_outputs)
+ _mesa_glsl_error(&loc, state,
+ "unsized output block arrays not allowed in "
+ "%s shader",
+ _mesa_shader_stage_to_string(state->stage));
+ } else {
+ /* by elimination, this is a uniform block array */
+ _mesa_glsl_error(&loc, state,
+ "unsized uniform block arrays not allowed in "
+ "%s shader",
+ _mesa_shader_stage_to_string(state->stage));
+ }
}
const glsl_type *block_array_type =
"not allowed");
}
+ if (this->layout.flags.q.explicit_binding)
+ validate_binding_qualifier(state, &loc, block_array_type,
+ &this->layout);
+
var = new(state) ir_variable(block_array_type,
this->instance_name,
var_mode);
if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
handle_geometry_shader_input_decl(state, loc, var);
+ else if ((state->stage == MESA_SHADER_TESS_CTRL ||
+ state->stage == MESA_SHADER_TESS_EVAL) && var_mode == ir_var_shader_in)
+ handle_tess_shader_input_decl(state, loc, var);
+ else if (state->stage == MESA_SHADER_TESS_CTRL && var_mode == ir_var_shader_out)
+ handle_tess_ctrl_shader_output_decl(state, loc, var);
+
+ for (unsigned i = 0; i < num_variables; i++) {
+ if (fields[i].type->is_unsized_array()) {
+ if (var_mode == ir_var_shader_storage) {
+ if (i != (num_variables - 1)) {
+ _mesa_glsl_error(&loc, state, "unsized array `%s' definition: "
+ "only last member of a shader storage block "
+ "can be defined as unsized array",
+ fields[i].name);
+ }
+ } else {
+ /* From GLSL ES 3.10 spec, section 4.1.9 "Arrays":
+ *
+ * "If an array is declared as the last member of a shader storage
+ * block and the size is not specified at compile-time, it is
+ * sized at run-time. In all other cases, arrays are sized only
+ * at compile-time."
+ */
+ if (state->es_shader) {
+ _mesa_glsl_error(&loc, state, "unsized array `%s' definition: "
+ "only last member of a shader storage block "
+ "can be defined as unsized array",
+ fields[i].name);
+ }
+ }
+ }
+ }
if (ir_variable *earlier =
state->symbols->get_variable(this->instance_name)) {
var->data.explicit_binding = this->layout.flags.q.explicit_binding;
var->data.binding = this->layout.binding;
+ if (var->type->is_unsized_array()) {
+ if (var->is_in_shader_storage_block()) {
+ if (!is_unsized_array_last_element(var)) {
+ _mesa_glsl_error(&loc, state, "unsized array `%s' definition: "
+ "only last member of a shader storage block "
+ "can be defined as unsized array",
+ var->name);
+ }
+ var->data.from_ssbo_unsized_array = true;
+ } else {
+ /* From GLSL ES 3.10 spec, section 4.1.9 "Arrays":
+ *
+ * "If an array is declared as the last member of a shader storage
+ * block and the size is not specified at compile-time, it is
+ * sized at run-time. In all other cases, arrays are sized only
+ * at compile-time."
+ */
+ if (state->es_shader) {
+ _mesa_glsl_error(&loc, state, "unsized array `%s' definition: "
+ "only last member of a shader storage block "
+ "can be defined as unsized array",
+ var->name);
+ }
+ }
+ }
+
state->symbols->add_variable(var);
instructions->push_tail(var);
}
continue;
/* Note: Not all tessellation control shader output are arrays. */
- if (!var->type->is_unsized_array())
- continue;
+ if (!var->type->is_unsized_array() || var->data.patch)
+ continue;
if (var->data.max_array_access >= num_vertices) {
_mesa_glsl_error(&loc, state,