aboutsummaryrefslogtreecommitdiffstats
path: root/src/glsl/ast_to_hir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl/ast_to_hir.cpp')
-rw-r--r--src/glsl/ast_to_hir.cpp586
1 files changed, 495 insertions, 91 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 6896b700cd6..fa2c09d2697 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -54,6 +54,7 @@
#include "ast.h"
#include "glsl_types.h"
#include "program/hash_table.h"
+#include "main/shaderobj.h"
#include "ir.h"
#include "ir_builder.h"
@@ -79,6 +80,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
state->toplevel_ir = instructions;
state->gs_input_prim_type_specified = false;
+ state->tcs_output_vertices_specified = false;
state->cs_input_local_size_specified = false;
/* Section 4.2 of the GLSL 1.20 specification states:
@@ -639,6 +641,34 @@ shift_result_type(const struct glsl_type *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
*
* Validates that \c rhs can be assigned to some location. If the types are
@@ -654,9 +684,9 @@ shift_result_type(const struct glsl_type *type_a,
* 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
@@ -665,9 +695,28 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
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,
@@ -677,8 +726,8 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
* 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 {
@@ -689,8 +738,8 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
}
/* 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;
}
@@ -698,7 +747,7 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
"%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;
}
@@ -733,7 +782,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
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) {
@@ -795,7 +844,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
}
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;
@@ -972,6 +1021,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_FUNCTION:
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.
*/
@@ -1271,7 +1321,14 @@ ast_expression::do_hir(exec_list *instructions,
* applied to one operand that can make them match, in which
* case this conversion is done."
*/
- if ((!apply_implicit_conversion(op[0]->type, op[1], state)
+
+ if (op[0]->type == glsl_type::void_type || op[1]->type == glsl_type::void_type) {
+ _mesa_glsl_error(& loc, state, "`%s': wrong operand types: "
+ "no operation `%1$s' exists that takes a left-hand "
+ "operand of type 'void' or a right operand of type "
+ "'void'", (this->oper == ast_equal) ? "==" : "!=");
+ error_emitted = true;
+ } else if ((!apply_implicit_conversion(op[0]->type, op[1], state)
&& !apply_implicit_conversion(op[1]->type, op[0], state))
|| (op[0]->type != op[1]->type)) {
_mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
@@ -2008,7 +2065,7 @@ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state,
const glsl_type *type,
ir_variable *var)
{
- if (var && !var->is_in_uniform_block()) {
+ if (var && !var->is_in_buffer_block()) {
/* Layout qualifiers may only apply to interface blocks and fields in
* them.
*/
@@ -2045,9 +2102,10 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
ir_variable *var,
const ast_type_qualifier *qual)
{
- if (var->data.mode != ir_var_uniform) {
+ if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage) {
_mesa_glsl_error(loc, state,
- "the \"binding\" qualifier only applies to uniforms");
+ "the \"binding\" qualifier only applies to uniforms and "
+ "shader storage buffer objects");
return false;
}
@@ -2071,13 +2129,31 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
*
* The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS.
*/
- if (max_index >= ctx->Const.MaxUniformBufferBindings) {
+ if (var->data.mode == ir_var_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)",
qual->binding, elements,
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
+ * implementation-dependent maximum number of uniform buffer bindings, a
+ * compile-time error will occur. When the binding identifier is used
+ * with a uniform or shader storage block instanced as an array of size
+ * 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 &&
+ 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)",
+ qual->binding, elements,
+ ctx->Const.MaxShaderStorageBufferBindings);
+ return false;
+ }
} else if (var->type->is_sampler() ||
(var->type->is_array() && var->type->fields.array->is_sampler())) {
/* Samplers. From page 63 of the GLSL 4.20 specification:
@@ -2206,6 +2282,8 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
* input output
* ----- ------
* vertex explicit_loc sso
+ * tess control sso sso
+ * tess eval sso sso
* geometry sso sso
* fragment sso explicit_loc
*/
@@ -2228,6 +2306,8 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
fail = true;
break;
+ case MESA_SHADER_TESS_CTRL:
+ case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY:
if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) {
if (!state->check_separate_shader_objects_allowed(loc, var))
@@ -2287,8 +2367,13 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
: (qual->location + VARYING_SLOT_VAR0);
break;
+ 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:
@@ -2439,6 +2524,12 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
}
}
+ 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)))
@@ -2455,6 +2546,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
var->data.stream = qual->stream;
}
+ if (qual->flags.q.patch)
+ var->data.patch = 1;
+
if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
var->type = glsl_type::error_type;
_mesa_glsl_error(loc, state,
@@ -2502,6 +2596,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
var->data.mode = ir_var_shader_out;
else if (qual->flags.q.uniform)
var->data.mode = ir_var_uniform;
+ else if (qual->flags.q.buffer)
+ var->data.mode = ir_var_shader_storage;
if (!is_parameter && is_varying_var(var, state->stage)) {
/* User-defined ins/outs are not permitted in compute shaders. */
@@ -2565,7 +2661,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
case MESA_SHADER_VERTEX:
if (var->data.mode == ir_var_shader_out)
var->data.invariant = true;
- break;
+ break;
+ case MESA_SHADER_TESS_CTRL:
+ case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY:
if ((var->data.mode == ir_var_shader_in)
|| (var->data.mode == ir_var_shader_out))
@@ -2984,6 +3082,15 @@ process_initializer(ir_variable *var, ast_declaration *decl,
"cannot initialize uniforms");
}
+ /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec:
+ *
+ * "Buffer variables cannot have initializers."
+ */
+ if (var->data.mode == ir_var_shader_storage) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "SSBO variables cannot have initializers");
+ }
+
/* From section 4.1.7 of the GLSL 4.40 spec:
*
* "Opaque variables [...] are initialized only through the
@@ -3019,7 +3126,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
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;
@@ -3105,30 +3212,13 @@ process_initializer(ir_variable *var, ast_declaration *decl,
return result;
}
-
-/**
- * Do additional processing necessary for geometry shader input declarations
- * (this covers both interface blocks arrays and bare input variables).
- */
static void
-handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
- YYLTYPE loc, ir_variable *var)
+validate_layout_qualifier_vertex_count(struct _mesa_glsl_parse_state *state,
+ YYLTYPE loc, ir_variable *var,
+ unsigned num_vertices,
+ unsigned *size,
+ const char *var_category)
{
- unsigned num_vertices = 0;
- if (state->gs_input_prim_type_specified) {
- num_vertices = vertices_per_prim(state->in_qualifier->prim_type);
- }
-
- /* Geometry shader input variables must be arrays. Caller should have
- * reported an error for this.
- */
- if (!var->type->is_array()) {
- assert(state->error);
-
- /* To avoid cascading failures, short circuit the checks below. */
- return;
- }
-
if (var->type->is_unsized_array()) {
/* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec says:
*
@@ -3138,6 +3228,8 @@ handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
*
* Followed by a table mapping each allowed input layout qualifier to
* the corresponding input length.
+ *
+ * Similarly for tessellation control shader outputs.
*/
if (num_vertices != 0)
var->type = glsl_type::get_array_instance(var->type->fields.array,
@@ -3164,22 +3256,101 @@ handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
*/
if (num_vertices != 0 && var->type->length != num_vertices) {
_mesa_glsl_error(&loc, state,
- "geometry shader input size contradicts previously"
- " declared layout (size is %u, but layout requires a"
- " size of %u)", var->type->length, num_vertices);
- } else if (state->gs_input_size != 0 &&
- var->type->length != state->gs_input_size) {
+ "%s size contradicts previously declared layout "
+ "(size is %u, but layout requires a size of %u)",
+ var_category, var->type->length, num_vertices);
+ } else if (*size != 0 && var->type->length != *size) {
_mesa_glsl_error(&loc, state,
- "geometry shader input sizes are "
- "inconsistent (size is %u, but a previous "
- "declaration has size %u)",
- var->type->length, state->gs_input_size);
+ "%s sizes are inconsistent (size is %u, but a "
+ "previous declaration has size %u)",
+ var_category, var->type->length, *size);
} else {
- state->gs_input_size = var->type->length;
+ *size = var->type->length;
}
}
}
+static void
+handle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state,
+ YYLTYPE loc, ir_variable *var)
+{
+ unsigned num_vertices = 0;
+
+ if (state->tcs_output_vertices_specified) {
+ num_vertices = state->out_qualifier->vertices;
+ }
+
+ if (!var->type->is_array() && !var->data.patch) {
+ _mesa_glsl_error(&loc, state,
+ "tessellation control shader outputs must be arrays");
+
+ /* To avoid cascading failures, short circuit the checks below. */
+ return;
+ }
+
+ if (var->data.patch)
+ return;
+
+ validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
+ &state->tcs_output_size,
+ "geometry shader input");
+}
+
+/**
+ * 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 void
+handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
+ YYLTYPE loc, ir_variable *var)
+{
+ unsigned num_vertices = 0;
+
+ if (state->gs_input_prim_type_specified) {
+ num_vertices = vertices_per_prim(state->in_qualifier->prim_type);
+ }
+
+ /* Geometry shader input variables must be arrays. Caller should have
+ * reported an error for this.
+ */
+ if (!var->type->is_array()) {
+ assert(state->error);
+
+ /* To avoid cascading failures, short circuit the checks below. */
+ return;
+ }
+
+ validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
+ &state->gs_input_size,
+ "geometry shader input");
+}
void
validate_identifier(const char *identifier, YYLTYPE loc,
@@ -3358,6 +3529,18 @@ ast_declarator_list::hir(exec_list *instructions,
decl_type = this->type->glsl_type(& type_name, state);
+ /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec:
+ * "Buffer variables may only be declared inside interface blocks
+ * (section 4.3.9 “Interface Blocks”), which are then referred to as
+ * shader storage blocks. It is a compile-time error to declare buffer
+ * variables at global scope (outside a block)."
+ */
+ if (type->qualifier.flags.q.buffer && !decl_type->is_interface()) {
+ _mesa_glsl_error(&loc, state,
+ "buffer variables cannot be declared outside "
+ "interface blocks");
+ }
+
/* An offset-qualified atomic counter declaration sets the default
* offset for the next declaration within the same atomic counter
* buffer.
@@ -3431,7 +3614,7 @@ ast_declarator_list::hir(exec_list *instructions,
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.
*/
@@ -3449,10 +3632,24 @@ ast_declarator_list::hir(exec_list *instructions,
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
@@ -3524,6 +3721,8 @@ ast_declarator_list::hir(exec_list *instructions,
*/
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) {
@@ -3662,6 +3861,9 @@ ast_declarator_list::hir(exec_list *instructions,
}
}
}
+ } 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();
@@ -3757,6 +3959,13 @@ ast_declarator_list::hir(exec_list *instructions,
}
}
}
+
+ 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,
@@ -3880,6 +4089,33 @@ ast_declarator_list::hir(exec_list *instructions,
}
+ /* From section 4.3.4 of the GLSL 4.00 spec:
+ * "Input variables may not be declared using the patch in qualifier
+ * in tessellation control or geometry shaders."
+ *
+ * From section 4.3.6 of the GLSL 4.00 spec:
+ * "It is an error to use patch out in a vertex, tessellation
+ * evaluation, or geometry shader."
+ *
+ * This doesn't explicitly forbid using them in a fragment shader, but
+ * that's probably just an oversight.
+ */
+ if (state->stage != MESA_SHADER_TESS_EVAL
+ && this->type->qualifier.flags.q.patch
+ && this->type->qualifier.flags.q.in) {
+
+ _mesa_glsl_error(&loc, state, "'patch in' can only be used in a "
+ "tessellation evaluation shader");
+ }
+
+ if (state->stage != MESA_SHADER_TESS_CTRL
+ && this->type->qualifier.flags.q.patch
+ && this->type->qualifier.flags.q.out) {
+
+ _mesa_glsl_error(&loc, state, "'patch out' can only be used in a "
+ "tessellation control shader");
+ }
+
/* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
*/
if (this->type->qualifier.precision != ast_precision_none) {
@@ -3891,9 +4127,7 @@ ast_declarator_list::hir(exec_list *instructions,
* an array of that type.
*/
if (!(this->type->qualifier.precision == ast_precision_none
- || precision_qualifier_allowed(var->type)
- || (var->type->is_array()
- && precision_qualifier_allowed(var->type->fields.array)))) {
+ || precision_qualifier_allowed(var->type->without_array()))) {
_mesa_glsl_error(&loc, state,
"precision qualifiers apply only to floating point"
@@ -4196,6 +4430,7 @@ ast_function::hir(exec_list *instructions,
ir_function *f = NULL;
ir_function_signature *sig = NULL;
exec_list hir_parameters;
+ YYLTYPE loc = this->get_location();
const char *const name = identifier;
@@ -4247,6 +4482,17 @@ ast_function::hir(exec_list *instructions,
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."
*/
@@ -4284,15 +4530,15 @@ ast_function::hir(exec_list *instructions,
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);
}
@@ -4379,6 +4625,44 @@ ast_function::hir(exec_list *instructions,
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;
@@ -5277,8 +5561,9 @@ ast_type_specifier::hir(exec_list *instructions,
* \c glsl_struct_field to describe the members.
*
* If we're processing an interface block, var_mode should be the type of the
- * interface block (ir_var_shader_in, ir_var_shader_out, or ir_var_uniform).
- * If we're processing a structure, var_mode should be ir_var_auto.
+ * interface block (ir_var_shader_in, ir_var_shader_out, ir_var_uniform or
+ * ir_var_shader_storage). If we're processing a structure, var_mode should be
+ * ir_var_auto.
*
* \return
* The number of fields processed. A pointer to the array structure fields is
@@ -5351,19 +5636,19 @@ ast_process_structure_or_interface_block(exec_list *instructions,
if (is_interface && field_type->contains_opaque()) {
YYLTYPE loc = decl_list->get_location();
_mesa_glsl_error(&loc, state,
- "uniform in non-default uniform block contains "
+ "uniform/buffer in non-default interface block contains "
"opaque variable");
}
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 or "
- "uniform block");
+ _mesa_glsl_error(&loc, state, "atomic counter in structure, "
+ "shader storage block or uniform block");
}
if (field_type->contains_image()) {
@@ -5373,7 +5658,8 @@ ast_process_structure_or_interface_block(exec_list *instructions,
*/
YYLTYPE loc = decl_list->get_location();
_mesa_glsl_error(&loc, state,
- "image in structure or uniform block");
+ "image in structure, shader storage block or "
+ "uniform block");
}
const struct ast_type_qualifier *const qual =
@@ -5382,9 +5668,9 @@ ast_process_structure_or_interface_block(exec_list *instructions,
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 "
- "members");
+ "uniform/shader storage block layout qualifiers "
+ "std140, packed, and shared can only be applied "
+ "to uniform/shader storage blocks, not members");
}
if (qual->flags.q.constant) {
@@ -5403,15 +5689,16 @@ ast_process_structure_or_interface_block(exec_list *instructions,
interpret_interpolation_qualifier(qual, var_mode, state, &loc);
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
fields[i].sample = qual->flags.q.sample ? 1 : 0;
+ fields[i].patch = qual->flags.q.patch ? 1 : 0;
/* Only save explicitly defined streams in block's field */
fields[i].stream = qual->flags.q.explicit_stream ? qual->stream : -1;
if (qual->flags.q.row_major || qual->flags.q.column_major) {
- if (!qual->flags.q.uniform) {
+ if (!qual->flags.q.uniform && !qual->flags.q.buffer) {
_mesa_glsl_error(&loc, state,
"row_major and column_major can only be "
- "applied to uniform interface blocks");
+ "applied to interface blocks");
} else
validate_matrix_layout_for_type(state, &loc, field_type, NULL);
}
@@ -5608,6 +5895,9 @@ ast_interface_block::hir(exec_list *instructions,
} else if (this->layout.flags.q.uniform) {
var_mode = ir_var_uniform;
iface_type_name = "uniform";
+ } else if (this->layout.flags.q.buffer) {
+ var_mode = ir_var_shader_storage;
+ iface_type_name = "buffer";
} else {
var_mode = ir_var_auto;
iface_type_name = "UNKNOWN";
@@ -5692,16 +5982,28 @@ ast_interface_block::hir(exec_list *instructions,
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:
@@ -5734,6 +6036,8 @@ ast_interface_block::hir(exec_list *instructions,
earlier_per_vertex->fields.structure[j].centroid;
fields[i].sample =
earlier_per_vertex->fields.structure[j].sample;
+ fields[i].patch =
+ earlier_per_vertex->fields.structure[j].patch;
}
}
@@ -5787,8 +6091,18 @@ ast_interface_block::hir(exec_list *instructions,
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:
*
@@ -5834,16 +6148,39 @@ ast_interface_block::hir(exec_list *instructions,
* 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 =
@@ -5877,6 +6214,11 @@ ast_interface_block::hir(exec_list *instructions,
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);
if (ir_variable *earlier =
state->symbols->get_variable(this->instance_name)) {
@@ -5917,6 +6259,7 @@ ast_interface_block::hir(exec_list *instructions,
var->data.interpolation = fields[i].interpolation;
var->data.centroid = fields[i].centroid;
var->data.sample = fields[i].sample;
+ var->data.patch = fields[i].patch;
var->init_interface_type(block_type);
if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
@@ -5965,8 +6308,8 @@ ast_interface_block::hir(exec_list *instructions,
if (state->symbols->get_variable(var->name) != NULL)
_mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
- /* Propagate the "binding" keyword into this UBO's fields;
- * the UBO declaration itself doesn't get an ir_variable unless it
+ /* Propagate the "binding" keyword into this UBO/SSBO's fields.
+ * The UBO declaration itself doesn't get an ir_variable unless it
* has an instance name. This is ugly.
*/
var->data.explicit_binding = this->layout.flags.q.explicit_binding;
@@ -6025,6 +6368,67 @@ ast_interface_block::hir(exec_list *instructions,
ir_rvalue *
+ast_tcs_output_layout::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ YYLTYPE loc = this->get_location();
+
+ /* If any tessellation control output layout declaration preceded this
+ * one, make sure it was consistent with this one.
+ */
+ if (state->tcs_output_vertices_specified &&
+ state->out_qualifier->vertices != this->vertices) {
+ _mesa_glsl_error(&loc, state,
+ "tessellation control shader output layout does not "
+ "match previous declaration");
+ return NULL;
+ }
+
+ /* If any shader outputs occurred before this declaration and specified an
+ * array size, make sure the size they specified is consistent with the
+ * primitive type.
+ */
+ unsigned num_vertices = this->vertices;
+ if (state->tcs_output_size != 0 && state->tcs_output_size != num_vertices) {
+ _mesa_glsl_error(&loc, state,
+ "this tessellation control shader output layout "
+ "specifies %u vertices, but a previous output "
+ "is declared with size %u",
+ num_vertices, state->tcs_output_size);
+ return NULL;
+ }
+
+ state->tcs_output_vertices_specified = true;
+
+ /* If any shader outputs occurred before this declaration and did not
+ * specify an array size, their size is determined now.
+ */
+ foreach_in_list (ir_instruction, node, instructions) {
+ ir_variable *var = node->as_variable();
+ if (var == NULL || var->data.mode != ir_var_shader_out)
+ continue;
+
+ /* Note: Not all tessellation control shader output are arrays. */
+ if (!var->type->is_unsized_array() || var->data.patch)
+ continue;
+
+ if (var->data.max_array_access >= num_vertices) {
+ _mesa_glsl_error(&loc, state,
+ "this tessellation control shader output layout "
+ "specifies %u vertices, but an access to element "
+ "%u of output `%s' already exists", num_vertices,
+ var->data.max_array_access, var->name);
+ } else {
+ var->type = glsl_type::get_array_instance(var->type->fields.array,
+ num_vertices);
+ }
+ }
+
+ return NULL;
+}
+
+
+ir_rvalue *
ast_gs_input_layout::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{