glsl: Move is_builtin flag back to ir_function_signature.
[mesa.git] / src / glsl / ir.h
index b6cd1bae31cacf390d47451118b9a8d211ad8622..0d933024df08a9ff9abe095000b0051790b75ef0 100644 (file)
@@ -60,7 +60,7 @@ enum ir_node_type {
    ir_type_return,
    ir_type_swizzle,
    ir_type_texture,
-   ir_type_max, /**< maximum ir_type enum number, for validation */
+   ir_type_max /**< maximum ir_type enum number, for validation */
 };
 
 /**
@@ -76,7 +76,8 @@ public:
 
    virtual void accept(ir_visitor *) = 0;
    virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
-   virtual ir_instruction *clone(struct hash_table *ht) const = 0;
+   virtual ir_instruction *clone(void *mem_ctx,
+                                struct hash_table *ht) const = 0;
 
    /**
     * \name IR instruction downcast functions
@@ -106,15 +107,16 @@ protected:
    ir_instruction()
    {
       ir_type = ir_type_unset;
+      type = NULL;
    }
 };
 
 
 class ir_rvalue : public ir_instruction {
 public:
-   class ir_constant *constant_expression_value();
+   virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0;
 
-   virtual ir_rvalue *clone(struct hash_table *) const = 0;
+   virtual ir_constant *constant_expression_value() = 0;
 
    virtual ir_rvalue * as_rvalue()
    {
@@ -150,10 +152,7 @@ public:
    }
 
 protected:
-   ir_rvalue()
-   {
-      /* empty */
-   }
+   ir_rvalue();
 };
 
 
@@ -162,7 +161,8 @@ enum ir_variable_mode {
    ir_var_uniform,
    ir_var_in,
    ir_var_out,
-   ir_var_inout
+   ir_var_inout,
+   ir_var_temporary    /**< Temporary variable generated during compilation. */
 };
 
 enum ir_variable_interpolation {
@@ -174,9 +174,9 @@ enum ir_variable_interpolation {
 
 class ir_variable : public ir_instruction {
 public:
-   ir_variable(const struct glsl_type *, const char *);
+   ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
 
-   virtual ir_variable *clone(struct hash_table *ht) const;
+   virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const;
 
    virtual ir_variable *as_variable()
    {
@@ -194,10 +194,10 @@ public:
    /**
     * Get the string value for the interpolation qualifier
     *
-    * \return
-    * If none of \c shader_in or \c shader_out is set, an empty string will
-    * be returned.  Otherwise the string that would be used in a shader to
-    * specify \c mode will be returned.
+    * \return The string that would be used in a shader to specify \c
+    * mode will be returned.
+    *
+    * This function should only be used on a shader input or output variable.
     */
    const char *interpolation_string() const;
 
@@ -221,12 +221,6 @@ public:
    unsigned read_only:1;
    unsigned centroid:1;
    unsigned invariant:1;
-   /** If the variable is initialized outside of the scope of the shader */
-   unsigned shader_in:1;
-   /**
-    * If the variable value is later used outside of the scope of the shader.
-    */
-   unsigned shader_out:1;
 
    unsigned mode:3;
    unsigned interpolation:2;
@@ -239,6 +233,10 @@ public:
     */
    unsigned array_lvalue:1;
 
+   /* ARB_fragment_coord_conventions */
+   unsigned origin_upper_left:1;
+   unsigned pixel_center_integer:1;
+
    /**
     * Storage location of the base of this variable
     *
@@ -280,7 +278,8 @@ class ir_function_signature : public ir_instruction {
 public:
    ir_function_signature(const glsl_type *return_type);
 
-   virtual ir_function_signature *clone(struct hash_table *ht) const;
+   virtual ir_function_signature *clone(void *mem_ctx,
+                                       struct hash_table *ht) const;
 
    virtual void accept(ir_visitor *v)
    {
@@ -344,7 +343,7 @@ public:
    unsigned is_defined:1;
 
    /** Whether or not this function signature is a built-in. */
-   unsigned is_built_in:1;
+   unsigned is_builtin:1;
 
    /** Body of instructions in the function. */
    struct exec_list body;
@@ -366,7 +365,7 @@ class ir_function : public ir_instruction {
 public:
    ir_function(const char *name);
 
-   virtual ir_function *clone(struct hash_table *ht) const;
+   virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const;
 
    virtual ir_function *as_function()
    {
@@ -411,7 +410,9 @@ public:
     */
    const char *name;
 
-private:
+   /** Whether or not this function has a signature that is a built-in. */
+   bool has_builtin_signature();
+
    /**
     * List of ir_function_signature for each overloaded function with this name.
     */
@@ -436,7 +437,7 @@ public:
       ir_type = ir_type_if;
    }
 
-   virtual ir_if *clone(struct hash_table *ht) const;
+   virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const;
 
    virtual ir_if *as_if()
    {
@@ -463,12 +464,9 @@ public:
  */
 class ir_loop : public ir_instruction {
 public:
-   ir_loop() : from(NULL), to(NULL), increment(NULL), counter(NULL)
-   {
-      ir_type = ir_type_loop;
-   }
+   ir_loop();
 
-   virtual ir_loop *clone(struct hash_table *ht) const;
+   virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const;
 
    virtual void accept(ir_visitor *v)
    {
@@ -495,21 +493,51 @@ public:
 
    /**
     * \name Loop counter and controls
+    *
+    * Represents a loop like a FORTRAN \c do-loop.
+    *
+    * \note
+    * If \c from and \c to are the same value, the loop will execute once.
     */
    /*@{*/
-   ir_rvalue *from;
-   ir_rvalue *to;
+   ir_rvalue *from;             /** Value of the loop counter on the first
+                                * iteration of the loop.
+                                */
+   ir_rvalue *to;               /** Value of the loop counter on the last
+                                * iteration of the loop.
+                                */
    ir_rvalue *increment;
    ir_variable *counter;
+
+   /**
+    * Comparison operation in the loop terminator.
+    *
+    * If any of the loop control fields are non-\c NULL, this field must be
+    * one of \c ir_binop_less, \c ir_binop_greater, \c ir_binop_lequal,
+    * \c ir_binop_gequal, \c ir_binop_equal, or \c ir_binop_nequal.
+    */
+   int cmp;
    /*@}*/
 };
 
 
-class ir_assignment : public ir_rvalue {
+class ir_assignment : public ir_instruction {
 public:
    ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
 
-   virtual ir_assignment *clone(struct hash_table *ht) const;
+   /**
+    * Construct an assignment with an explicit write mask
+    *
+    * \note
+    * Since a write mask is supplied, the LHS must already be a bare
+    * \c ir_dereference.  The cannot be any swizzles in the LHS.
+    */
+   ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition,
+                unsigned write_mask);
+
+   virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
+
+   virtual ir_constant *constant_expression_value();
 
    virtual void accept(ir_visitor *v)
    {
@@ -523,10 +551,32 @@ public:
       return this;
    }
 
+   /**
+    * Get a whole variable written by an assignment
+    *
+    * If the LHS of the assignment writes a whole variable, the variable is
+    * returned.  Otherwise \c NULL is returned.  Examples of whole-variable
+    * assignment are:
+    *
+    *  - Assigning to a scalar
+    *  - Assigning to all components of a vector
+    *  - Whole array (or matrix) assignment
+    *  - Whole structure assignment
+    */
+   ir_variable *whole_variable_written();
+
+   /**
+    * Set the LHS of an assignment
+    */
+   void set_lhs(ir_rvalue *lhs);
+
    /**
     * Left-hand side of the assignment.
+    *
+    * This should be treated as read only.  If you need to set the LHS of an
+    * assignment, use \c ir_assignment::set_lhs.
     */
-   ir_rvalue *lhs;
+   ir_dereference *lhs;
 
    /**
     * Value being assigned
@@ -537,6 +587,16 @@ public:
     * Optional condition for the assignment.
     */
    ir_rvalue *condition;
+
+
+   /**
+    * Component mask written
+    *
+    * For non-vector types in the LHS, this field will be zero.  For vector
+    * types, a bit will be set for each component that is written.  Note that
+    * for \c vec2 and \c vec3 types only the lower bits will ever be set.
+    */
+   unsigned write_mask:4;
 };
 
 /* Update ir_expression::num_operands() and operator_strs when
@@ -551,8 +611,8 @@ enum ir_expression_operation {
    ir_unop_rcp,
    ir_unop_rsq,
    ir_unop_sqrt,
-   ir_unop_exp,
-   ir_unop_log,
+   ir_unop_exp,      /**< Log base e on gentype */
+   ir_unop_log,             /**< Natural log on gentype */
    ir_unop_exp2,
    ir_unop_log2,
    ir_unop_f2i,      /**< Float-to-integer conversion. */
@@ -562,6 +622,7 @@ enum ir_expression_operation {
    ir_unop_i2b,      /**< int-to-boolean conversion */
    ir_unop_b2i,      /**< Boolean-to-int conversion */
    ir_unop_u2f,      /**< Unsigned-to-float conversion. */
+   ir_unop_any,
 
    /**
     * \name Unary floating-point rounding operations.
@@ -612,7 +673,15 @@ enum ir_expression_operation {
    ir_binop_greater,
    ir_binop_lequal,
    ir_binop_gequal,
+   /**
+    * Returns single boolean for whether all components of operands[0]
+    * equal the components of operands[1].
+    */
    ir_binop_equal,
+   /**
+    * Returns single boolean for whether any component of operands[0]
+    * is not equal to the corresponding component of operands[1].
+    */
    ir_binop_nequal,
    /*@}*/
 
@@ -649,7 +718,9 @@ public:
       return this;
    }
 
-   virtual ir_expression *clone(struct hash_table *ht) const;
+   virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
+
+   virtual ir_constant *constant_expression_value();
 
    static unsigned int get_num_operands(ir_expression_operation);
    unsigned int get_num_operands() const
@@ -662,6 +733,12 @@ public:
     */
    const char *operator_string();
 
+   /**
+    * Return a string representing this expression's operator.
+    */
+   static const char *operator_string(ir_expression_operation);
+
+
    /**
     * Do a reverse-lookup to translate the given string into an operator.
     */
@@ -693,7 +770,9 @@ public:
       actual_parameters->move_nodes_to(& this->actual_parameters);
    }
 
-   virtual ir_call *clone(struct hash_table *ht) const;
+   virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
+
+   virtual ir_constant *constant_expression_value();
 
    virtual ir_call *as_call()
    {
@@ -788,7 +867,7 @@ public:
       this->ir_type = ir_type_return;
    }
 
-   virtual ir_return *clone(struct hash_table *) const;
+   virtual ir_return *clone(void *mem_ctx, struct hash_table *) const;
 
    virtual ir_return *as_return()
    {
@@ -833,7 +912,7 @@ public:
       this->loop = loop;
    }
 
-   virtual ir_loop_jump *clone(struct hash_table *) const;
+   virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const;
 
    virtual void accept(ir_visitor *v)
    {
@@ -872,10 +951,11 @@ public:
 
    ir_discard(ir_rvalue *cond)
    {
+      this->ir_type = ir_type_discard;
       this->condition = cond;
    }
 
-   virtual ir_discard *clone(struct hash_table *ht) const;
+   virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const;
 
    virtual void accept(ir_visitor *v)
    {
@@ -927,7 +1007,9 @@ public:
       this->ir_type = ir_type_texture;
    }
 
-   virtual ir_texture *clone(struct hash_table *) const;
+   virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
+
+   virtual ir_constant *constant_expression_value();
 
    virtual void accept(ir_visitor *v)
    {
@@ -1017,7 +1099,9 @@ public:
 
    ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
 
-   virtual ir_swizzle *clone(struct hash_table *) const;
+   virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
+
+   virtual ir_constant *constant_expression_value();
 
    virtual ir_swizzle *as_swizzle()
    {
@@ -1061,7 +1145,7 @@ private:
 
 class ir_dereference : public ir_rvalue {
 public:
-   virtual ir_dereference *clone(struct hash_table *) const = 0;
+   virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0;
 
    virtual ir_dereference *as_dereference()
    {
@@ -1081,7 +1165,10 @@ class ir_dereference_variable : public ir_dereference {
 public:
    ir_dereference_variable(ir_variable *var);
 
-   virtual ir_dereference_variable *clone(struct hash_table *) const;
+   virtual ir_dereference_variable *clone(void *mem_ctx,
+                                         struct hash_table *) const;
+
+   virtual ir_constant *constant_expression_value();
 
    virtual ir_dereference_variable *as_dereference_variable()
    {
@@ -1127,7 +1214,10 @@ public:
 
    ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
 
-   virtual ir_dereference_array *clone(struct hash_table *) const;
+   virtual ir_dereference_array *clone(void *mem_ctx,
+                                      struct hash_table *) const;
+
+   virtual ir_constant *constant_expression_value();
 
    virtual ir_dereference_array *as_dereference_array()
    {
@@ -1163,7 +1253,10 @@ public:
 
    ir_dereference_record(ir_variable *var, const char *field);
 
-   virtual ir_dereference_record *clone(struct hash_table *) const;
+   virtual ir_dereference_record *clone(void *mem_ctx,
+                                       struct hash_table *) const;
+
+   virtual ir_constant *constant_expression_value();
 
    /**
     * Get the variable that is ultimately referenced by an r-value
@@ -1221,7 +1314,14 @@ public:
     */
    ir_constant(const ir_constant *c, unsigned i);
 
-   virtual ir_constant *clone(struct hash_table *) const;
+   /**
+    * Return a new ir_constant of the specified type containing all zeros.
+    */
+   static ir_constant *zero(void *mem_ctx, const glsl_type *type);
+
+   virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
+
+   virtual ir_constant *constant_expression_value();
 
    virtual ir_constant *as_constant()
    {
@@ -1249,6 +1349,8 @@ public:
    unsigned get_uint_component(unsigned i) const;
    /*@}*/
 
+   ir_constant *get_array_element(unsigned i) const;
+
    ir_constant *get_record_field(const char *name);
 
    /**
@@ -1265,6 +1367,10 @@ public:
     */
    union ir_constant_data value;
 
+   /* Array elements */
+   ir_constant **array_elements;
+
+   /* Structure fields */
    exec_list components;
 
 private:
@@ -1286,7 +1392,7 @@ void validate_ir_tree(exec_list *instructions);
  * \param out  List to hold the cloned instructions
  */
 void
-clone_ir_list(exec_list *out, const exec_list *in);
+clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in);
 
 extern void
 _mesa_glsl_initialize_variables(exec_list *instructions,
@@ -1296,4 +1402,22 @@ extern void
 _mesa_glsl_initialize_functions(exec_list *instructions,
                                struct _mesa_glsl_parse_state *state);
 
+extern void
+_mesa_glsl_release_functions(void);
+
+extern void
+reparent_ir(exec_list *list, void *mem_ctx);
+
+struct glsl_symbol_table;
+
+extern void
+import_prototypes(const exec_list *source, exec_list *dest,
+                 struct glsl_symbol_table *symbols, void *mem_ctx);
+
+extern bool
+ir_has_call(ir_instruction *ir);
+
+extern void
+do_set_program_inouts(exec_list *instructions, struct gl_program *prog);
+
 #endif /* IR_H */