From d4a24745b84be49b0ede285ef795847ebca70916 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Thu, 2 Aug 2012 08:18:12 -0700 Subject: [PATCH] glsl: Enable GLSL ES 3.00 features inherited from desktop GLSL. This patch turns on the following features for GLSL ES 3.00: - Array constructors, whole array assignment, and array comparisons. - Second and third operands of ?: may be arrays. - Use of "in" and "out" qualifiers on globals. - Bitwise and modulus operators. - Integral vertex shader inputs. - Range-checking of literal integers. - array.length method. - Function calls may be constant expressions. - Integral varyings must be qualified with "flat". - Interpolation and centroid qualifiers may not be applied to vertex shader inputs. Reviewed-by: Ian Romanick Reviewed-by: Kenneth Graunke Acked-by: Carl Worth --- src/glsl/ast_function.cpp | 7 +++-- src/glsl/ast_to_hir.cpp | 51 +++++++++++++++++++++++++------- src/glsl/glsl_lexer.ll | 2 +- src/glsl/glsl_parser_extras.h | 2 +- src/glsl/hir_field_selection.cpp | 2 +- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 8a5979fb3e2..b56a3c72339 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -275,9 +275,10 @@ generate_call(exec_list *instructions, ir_function_signature *sig, /* If the function call is a constant expression, don't generate any * instructions; just generate an ir_constant. * - * Function calls were first allowed to be constant expressions in GLSL 1.20. + * Function calls were first allowed to be constant expressions in GLSL + * 1.20 and GLSL ES 3.00. */ - if (state->is_version(120, 0)) { + if (state->is_version(120, 300)) { ir_constant *value = sig->constant_expression_value(actual_parameters, NULL); if (value != NULL) { return value; @@ -1243,7 +1244,7 @@ ast_function_expression::hir(exec_list *instructions, } if (constructor_type->is_array()) { - if (!state->check_version(120, 0, &loc, + if (!state->check_version(120, 300, &loc, "array constructors forbidden")) { return ir_rvalue::error_value(ctx); } diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 394a7ef4bd3..94b63f6823e 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -445,7 +445,7 @@ modulus_result_type(const struct glsl_type *type_a, const struct glsl_type *type_b, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { - if (!state->check_version(130, 0, loc, "operator '%%' is reserved")) { + if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) { return glsl_type::error_type; } @@ -690,13 +690,15 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, error_emitted = true; } else if (lhs->type->is_array() && - !state->check_version(120, 0, &lhs_loc, + !state->check_version(120, 300, &lhs_loc, "whole array assignment forbidden")) { /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: * * "Other binary or unary expressions, non-dereferenced * arrays, function names, swizzles with repeated fields, * and constants cannot be l-values." + * + * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00. */ error_emitted = true; } else if (!lhs->is_lvalue()) { @@ -1149,7 +1151,7 @@ ast_expression::hir(exec_list *instructions, "type", (this->oper == ast_equal) ? "==" : "!="); error_emitted = true; } else if ((op[0]->type->is_array() || op[1]->type->is_array()) && - !state->check_version(120, 0, &loc, + !state->check_version(120, 300, &loc, "array comparisons forbidden")) { error_emitted = true; } @@ -1416,7 +1418,7 @@ ast_expression::hir(exec_list *instructions, * be of any type other than an array." */ if (type->is_array() && - !state->check_version(120, 0, &loc, + !state->check_version(120, 300, &loc, "Second and third operands of ?: operator " "cannot be arrays")) { error_emitted = true; @@ -2602,10 +2604,10 @@ ast_declarator_list::hir(exec_list *instructions, * * Local variables can only use the qualifier const." * - * This is relaxed in GLSL 1.30. It is also relaxed by any extension - * that adds the 'layout' keyword. + * This is relaxed in GLSL 1.30 and GLSL ES 3.00. It is also relaxed by + * any extension that adds the 'layout' keyword. */ - if (!state->is_version(130, 0) + if (!state->is_version(130, 300) && !state->ARB_explicit_attrib_location_enable && !state->ARB_fragment_coord_conventions_enable) { if (this->type->qualifier.flags.q.out) { @@ -2697,6 +2699,13 @@ ast_declarator_list::hir(exec_list *instructions, * "The attribute qualifier can be used only with float, * floating-point vectors, and matrices. Attribute variables * cannot be declared as arrays or structures." + * + * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec: + * + * "Vertex shader inputs can only be float, floating-point + * vectors, matrices, signed and unsigned integers and integer + * vectors. Vertex shader inputs cannot be arrays or + * structures." */ const glsl_type *check_type = var->type->is_array() ? var->type->fields.array : var->type; @@ -2706,7 +2715,7 @@ ast_declarator_list::hir(exec_list *instructions, break; case GLSL_TYPE_UINT: case GLSL_TYPE_INT: - if (state->is_version(120, 0)) + if (state->is_version(120, 300)) break; /* FALLTHROUGH */ default: @@ -2733,8 +2742,16 @@ ast_declarator_list::hir(exec_list *instructions, * "If a vertex output is a signed or unsigned integer or integer * vector, then it must be qualified with the interpolation qualifier * flat." + * + * From section 4.3.4 of the GLSL 3.00 ES spec: + * "Fragment shader inputs that are signed or unsigned integers or + * integer vectors must be qualified with the interpolation qualifier + * flat." + * + * Since vertex outputs and fragment inputs must have matching + * qualifiers, these two requirements are equivalent. */ - if (state->is_version(130, 0) + if (state->is_version(130, 300) && state->target == vertex_shader && state->current_function == NULL && var->type->is_integer() @@ -2753,6 +2770,8 @@ ast_declarator_list::hir(exec_list *instructions, * "interpolation qualifiers may only precede the qualifiers in, * centroid in, out, or centroid out in a declaration. They do not apply * to the deprecated storage qualifiers varying or centroid varying." + * + * These deprecated storage qualifiers do not exist in GLSL ES 3.00. */ if (state->is_version(130, 0) && this->type->qualifier.has_interpolation() @@ -2779,8 +2798,14 @@ ast_declarator_list::hir(exec_list *instructions, * "Outputs from a vertex shader (out) and inputs to a fragment * shader (in) can be further qualified with one or more of these * interpolation qualifiers" + * + * From page 31 (page 37 of the PDF) of the GLSL ES 3.00 spec: + * "These interpolation qualifiers may only precede the qualifiers + * in, centroid in, out, or centroid out in a declaration. They do + * not apply to inputs into a vertex shader or outputs from a + * fragment shader." */ - if (state->is_version(130, 0) + if (state->is_version(130, 300) && this->type->qualifier.has_interpolation()) { const char *i = this->type->qualifier.interpolation_string(); @@ -2809,8 +2834,12 @@ ast_declarator_list::hir(exec_list *instructions, /* From section 4.3.4 of the GLSL 1.30 spec: * "It is an error to use centroid in in a vertex shader." + * + * From section 4.3.4 of the GLSL ES 3.00 spec: + * "It is an error to use centroid in or interpolation qualifiers in + * a vertex shader input." */ - if (state->is_version(130, 0) + if (state->is_version(130, 300) && this->type->qualifier.flags.q.centroid && this->type->qualifier.flags.q.in && state->target == vertex_shader) { diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll index e667e713292..af39512ed15 100644 --- a/src/glsl/glsl_lexer.ll +++ b/src/glsl/glsl_lexer.ll @@ -122,7 +122,7 @@ literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state, if (value > UINT_MAX) { /* Note that signed 0xffffffff is valid, not out of range! */ - if (state->is_version(130, 0)) { + if (state->is_version(130, 300)) { _mesa_glsl_error(lloc, state, "Literal value `%s' out of range", text); } else { diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 17f63c0b3c4..f05406abf0a 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -133,7 +133,7 @@ struct _mesa_glsl_parse_state { bool check_bitwise_operations_allowed(YYLTYPE *locp) { - return check_version(130, 0, locp, "bit-wise operations are forbidden"); + return check_version(130, 300, locp, "bit-wise operations are forbidden"); } struct gl_context *const ctx; diff --git a/src/glsl/hir_field_selection.cpp b/src/glsl/hir_field_selection.cpp index a18227f7b01..ac416d5dac4 100644 --- a/src/glsl/hir_field_selection.cpp +++ b/src/glsl/hir_field_selection.cpp @@ -72,7 +72,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr, } } else if (expr->subexpressions[1] != NULL) { /* Handle "method calls" in GLSL 1.20 - namely, array.length() */ - state->check_version(120, 0, &loc, "Methods not supported"); + state->check_version(120, 300, &loc, "Methods not supported"); ast_expression *call = expr->subexpressions[1]; assert(call->oper == ast_function_call); -- 2.30.2