glsl: Enable GLSL ES 3.00 features inherited from desktop GLSL.
authorPaul Berry <stereotype441@gmail.com>
Thu, 2 Aug 2012 15:18:12 +0000 (08:18 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 6 Dec 2012 20:13:21 +0000 (12:13 -0800)
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 <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Acked-by: Carl Worth <cworth@cworth.org>
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/glsl_lexer.ll
src/glsl/glsl_parser_extras.h
src/glsl/hir_field_selection.cpp

index 8a5979fb3e2a658859e53214a9cddd8158ffc448..b56a3c72339f657e99574db202696baf612e9e99 100644 (file)
@@ -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);
         }
index 394a7ef4bd3a19203289f88858d41a9de993ce39..94b63f6823e10f207307e548881f8a6287039244 100644 (file)
@@ -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) {
index e667e71329285d71bef74abee266d6cdfa9eeb25..af39512ed153169ac18dd6ac6ce0cfefc974b545 100644 (file)
@@ -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 {
index 17f63c0b3c4dd2436ab09915fdd5245ee04f0534..f05406abf0a091c359d5d7dc39f57c489f0c1f9e 100644 (file)
@@ -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;
index a18227f7b015d9dbec91f525b7e4e9b0e1f0e698..ac416d5dac464d8562e13120721913d9f681329e 100644 (file)
@@ -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);