mesa: set up gl_vert_result and gl_frag_attrib values for gl_ClipDistance.
[mesa.git] / src / glsl / ast_to_hir.cpp
index 3b87f0d56de8543fd2099e1bba5b0760ce37f0b0..ce29d5a87aa0ed1842e75dd1b346bd415e0cfbce 100644 (file)
@@ -66,6 +66,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 
    state->current_function = NULL;
 
+   state->toplevel_ir = instructions;
+
    /* Section 4.2 of the GLSL 1.20 specification states:
     * "The built-in functions are scoped in a scope outside the global scope
     *  users declare global variables in.  That is, a shader's global scope,
@@ -83,6 +85,10 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 
    foreach_list_typed (ast_node, ast, link, & state->translation_unit)
       ast->hir(instructions, state);
+
+   detect_recursion_unlinked(state, instructions);
+
+   state->toplevel_ir = NULL;
 }
 
 
@@ -447,9 +453,17 @@ modulus_result_type(const struct glsl_type *type_a,
     *    integer vectors. The operand types must both be signed or both be
     *    unsigned."
     */
-   if (!type_a->is_integer() || !type_b->is_integer()
-       || (type_a->base_type != type_b->base_type)) {
-      _mesa_glsl_error(loc, state, "type mismatch");
+   if (!type_a->is_integer()) {
+      _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer.");
+      return glsl_type::error_type;
+   }
+   if (!type_b->is_integer()) {
+      _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer.");
+      return glsl_type::error_type;
+   }
+   if (type_a->base_type != type_b->base_type) {
+      _mesa_glsl_error(loc, state,
+                      "operands of %% must have the same base type");
       return glsl_type::error_type;
    }
 
@@ -639,6 +653,16 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
    return NULL;
 }
 
+static void
+mark_whole_array_access(ir_rvalue *access)
+{
+   ir_dereference_variable *deref = access->as_dereference_variable();
+
+   if (deref && deref->var) {
+      deref->var->max_array_access = deref->type->length - 1;
+   }
+}
+
 ir_rvalue *
 do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
              ir_rvalue *lhs, ir_rvalue *rhs, bool is_initializer,
@@ -655,16 +679,20 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
                           lhs->variable_referenced()->name);
          error_emitted = true;
 
+      } else if (state->language_version <= 110 && lhs->type->is_array()) {
+        /* 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."
+         */
+        _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
+                         "allowed in GLSL 1.10 or GLSL ES 1.00.");
+        error_emitted = true;
       } else if (!lhs->is_lvalue()) {
         _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
         error_emitted = true;
       }
-
-      if (state->es_shader && lhs->type->is_array()) {
-        _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
-                         "allowed in GLSL ES 1.00.");
-        error_emitted = true;
-      }
    }
 
    ir_rvalue *new_rhs =
@@ -699,6 +727,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
                                                   rhs->type->array_size());
         d->type = var->type;
       }
+      mark_whole_array_access(rhs);
+      mark_whole_array_access(lhs);
    }
 
    /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
@@ -759,16 +789,6 @@ ast_node::hir(exec_list *instructions,
    return NULL;
 }
 
-static void
-mark_whole_array_access(ir_rvalue *access)
-{
-   ir_dereference_variable *deref = access->as_dereference_variable();
-
-   if (deref) {
-      deref->var->max_array_access = deref->type->length - 1;
-   }
-}
-
 static ir_rvalue *
 do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
 {
@@ -878,6 +898,44 @@ get_scalar_boolean_operand(exec_list *instructions,
    return new(ctx) ir_constant(true);
 }
 
+/**
+ * If name refers to a builtin array whose maximum allowed size is less than
+ * size, report an error and return true.  Otherwise return false.
+ */
+static bool
+check_builtin_array_max_size(const char *name, unsigned size,
+                             YYLTYPE loc, struct _mesa_glsl_parse_state *state)
+{
+   if ((strcmp("gl_TexCoord", name) == 0)
+       && (size > state->Const.MaxTextureCoords)) {
+      /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
+       *
+       *     "The size [of gl_TexCoord] can be at most
+       *     gl_MaxTextureCoords."
+       */
+      _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot "
+                       "be larger than gl_MaxTextureCoords (%u)\n",
+                       state->Const.MaxTextureCoords);
+      return true;
+   } else if (strcmp("gl_ClipDistance", name) == 0
+              && size > state->Const.MaxClipPlanes) {
+      /* From section 7.1 (Vertex Shader Special Variables) of the
+       * GLSL 1.30 spec:
+       *
+       *   "The gl_ClipDistance array is predeclared as unsized and
+       *   must be sized by the shader either redeclaring it with a
+       *   size or indexing it only with integral constant
+       *   expressions. ... The size can be at most
+       *   gl_MaxClipDistances."
+       */
+      _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot "
+                       "be larger than gl_MaxClipDistances (%u)\n",
+                       state->Const.MaxClipPlanes);
+      return true;
+   }
+   return false;
+}
+
 ir_rvalue *
 ast_expression::hir(exec_list *instructions,
                    struct _mesa_glsl_parse_state *state)
@@ -1535,8 +1593,15 @@ ast_expression::hir(exec_list *instructions,
             * FINISHME: array access limits be added to ir_dereference?
             */
            ir_variable *const v = array->whole_variable_referenced();
-           if ((v != NULL) && (unsigned(idx) > v->max_array_access))
+           if ((v != NULL) && (unsigned(idx) > v->max_array_access)) {
               v->max_array_access = idx;
+
+               /* Check whether this access will, as a side effect, implicitly
+                * cause the size of a built-in array to be too large.
+                */
+               if (check_builtin_array_max_size(v->name, idx+1, loc, state))
+                  error_emitted = true;
+            }
         }
       } else if (array->type->array_size() == 0) {
         _mesa_glsl_error(&loc, state, "unsized array index must be constant");
@@ -1755,11 +1820,6 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
       ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
       YYLTYPE loc = array_size->get_location();
 
-      /* FINISHME: Verify that the grammar forbids side-effects in array
-       * FINISHME: sizes.   i.e., 'vec4 [x = 12] data'
-       */
-      assert(dummy_instructions.is_empty());
-
       if (ir != NULL) {
         if (!ir->type->is_integer()) {
            _mesa_glsl_error(& loc, state, "array size must be integer type");
@@ -1776,6 +1836,14 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
            } else {
               assert(size->type == ir->type);
               length = size->value.u[0];
+
+               /* If the array size is const (and we've verified that
+                * it is) then no instructions should have been emitted
+                * when we converted it to HIR.  If they were emitted,
+                * then either the array size isn't const after all, or
+                * we are emitting unnecessary instructions.
+                */
+               assert(dummy_instructions.is_empty());
            }
         }
       }
@@ -1940,7 +2008,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
         break;
 
       case fragment_shader:
-        if (!global_scope || (var->mode != ir_var_in)) {
+        if (!global_scope || (var->mode != ir_var_out)) {
            fail = true;
            string = "output";
         }
@@ -2052,10 +2120,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
        var->depth_layout = ir_depth_layout_unchanged;
    else
        var->depth_layout = ir_depth_layout_none;
-
-   if (var->type->is_array() && state->language_version != 110) {
-      var->array_lvalue = true;
-   }
 }
 
 /**
@@ -2103,18 +2167,9 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl,
        * FINISHME: required or not.
        */
 
-      /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
-       *
-       *     "The size [of gl_TexCoord] can be at most
-       *     gl_MaxTextureCoords."
-       */
       const unsigned size = unsigned(var->type->array_size());
-      if ((strcmp("gl_TexCoord", var->name) == 0)
-         && (size > state->Const.MaxTextureCoords)) {
-        _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot "
-                         "be larger than gl_MaxTextureCoords (%u)\n",
-                         state->Const.MaxTextureCoords);
-      } else if ((size > 0) && (size <= earlier->max_array_access)) {
+      check_builtin_array_max_size(var->name, size, loc, state);
+      if ((size > 0) && (size <= earlier->max_array_access)) {
         _mesa_glsl_error(& loc, state, "array size must be > %u due to "
                          "previous access",
                          earlier->max_array_access);
@@ -2389,12 +2444,12 @@ ast_declarator_list::hir(exec_list *instructions,
 
    decl_type = this->type->specifier->glsl_type(& type_name, state);
    if (this->declarations.is_empty()) {
-      /* The only valid case where the declaration list can be empty is when
-       * the declaration is setting the default precision of a built-in type
-       * (e.g., 'precision highp vec4;').
-       */
-
       if (decl_type != NULL) {
+        /* Warn if this empty declaration is not for declaring a structure.
+         */
+        if (this->type->specifier->structure == NULL) {
+           _mesa_glsl_warning(&loc, state, "empty declaration");
+        }
       } else {
            _mesa_glsl_error(& loc, state, "incomplete declaration");
       }
@@ -2696,6 +2751,17 @@ ast_declarator_list::hir(exec_list *instructions,
                                                       : "and integer");
       }
 
+      /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+       *
+       *    "[Sampler types] can only be declared as function
+       *    parameters or uniform variables (see Section 4.3.5
+       *    "Uniform")".
+       */
+      if (var_type->contains_sampler() &&
+          !this->type->qualifier.flags.q.uniform) {
+         _mesa_glsl_error(&loc, state, "samplers must be declared uniform");
+      }
+
       /* Process the initializer and add its instructions to a temporary
        * list.  This list will be added to the instruction stream (below) after
        * the declaration is added.  This is done because in some cases (such as
@@ -2856,6 +2922,38 @@ ast_parameter_declarator::hir(exec_list *instructions,
     */
    apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);
 
+   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+    *
+    *    "Samplers cannot be treated as l-values; hence cannot be used
+    *    as out or inout function parameters, nor can they be assigned
+    *    into."
+    */
+   if ((var->mode == ir_var_inout || var->mode == ir_var_out)
+       && type->contains_sampler()) {
+      _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers");
+      type = glsl_type::error_type;
+   }
+
+   /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec:
+    *
+    *    "When calling a function, expressions that do not evaluate to
+    *     l-values cannot be passed to parameters declared as out or inout."
+    *
+    * 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."
+    *
+    * So for GLSL 1.10, passing an array as an out or inout parameter is not
+    * allowed.  This restriction is removed in GLSL 1.20, and in GLSL ES.
+    */
+   if ((var->mode == ir_var_inout || var->mode == ir_var_out)
+       && type->is_array() && state->language_version == 110) {
+      _mesa_glsl_error(&loc, state, "Arrays cannot be out or inout parameters in GLSL 1.10");
+      type = glsl_type::error_type;
+   }
+
    instructions->push_tail(var);
 
    /* Parameter declarations do not have r-values.
@@ -2893,23 +2991,16 @@ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
 
 
 void
-emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
-             ir_function *f)
+emit_function(_mesa_glsl_parse_state *state, ir_function *f)
 {
-   /* Emit the new function header */
-   if (state->current_function == NULL) {
-      instructions->push_tail(f);
-   } else {
-      /* IR invariants disallow function declarations or definitions nested
-       * within other function definitions.  Insert the new ir_function
-       * block in the instruction sequence before the ir_function block
-       * containing the current ir_function_signature.
-       */
-      ir_function *const curr =
-        const_cast<ir_function *>(state->current_function->function());
-
-      curr->insert_before(f);
-   }
+   /* IR invariants disallow function declarations or definitions
+    * nested within other function definitions.  But there is no
+    * requirement about the relative order of function declarations
+    * and definitions with respect to one another.  So simply insert
+    * the new ir_function block at the end of the toplevel instruction
+    * list.
+    */
+   state->toplevel_ir->push_tail(f);
 }
 
 
@@ -2924,6 +3015,12 @@ ast_function::hir(exec_list *instructions,
 
    const char *const name = identifier;
 
+   /* New functions are always added to the top-level IR instruction stream,
+    * so this instruction list pointer is ignored.  See also emit_function
+    * (called below).
+    */
+   (void) instructions;
+
    /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
     *
     *   "Function declarations (prototypes) cannot occur inside of functions;
@@ -2984,6 +3081,18 @@ ast_function::hir(exec_list *instructions,
                       "function `%s' return type has qualifiers", name);
    }
 
+   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+    *
+    *    "[Sampler types] can only be declared as function parameters
+    *    or uniform variables (see Section 4.3.5 "Uniform")".
+    */
+   if (return_type->contains_sampler()) {
+      YYLTYPE loc = this->get_location();
+      _mesa_glsl_error(&loc, state,
+                       "function `%s' return type can't contain a sampler",
+                       name);
+   }
+
    /* Verify that this function's signature either doesn't match a previously
     * seen signature for a function with the same name, or, if a match is found,
     * that the previously seen signature does not have an associated definition.
@@ -3024,7 +3133,7 @@ ast_function::hir(exec_list *instructions,
         return NULL;
       }
 
-      emit_function(state, instructions, f);
+      emit_function(state, f);
    }
 
    /* Verify the return type of main() */