nir: Move nir_cursor to nir.h.
[mesa.git] / src / glsl / ir.h
index fdc22edf133d7f585792f0ae7bc87c80d6c50e2b..ede8caa6e47b8b05fbb1368908102bec65aa1464 100644 (file)
@@ -78,6 +78,7 @@ enum ir_node_type {
    ir_type_discard,
    ir_type_emit_vertex,
    ir_type_end_primitive,
+   ir_type_barrier,
    ir_type_max, /**< maximum ir_type enum number, for validation */
    ir_type_unset = ir_type_max
 };
@@ -109,6 +110,31 @@ public:
    virtual ir_instruction *clone(void *mem_ctx,
                                 struct hash_table *ht) const = 0;
 
+   bool is_rvalue() const
+   {
+      return ir_type == ir_type_dereference_array ||
+             ir_type == ir_type_dereference_record ||
+             ir_type == ir_type_dereference_variable ||
+             ir_type == ir_type_constant ||
+             ir_type == ir_type_expression ||
+             ir_type == ir_type_swizzle ||
+             ir_type == ir_type_texture;
+   }
+
+   bool is_dereference() const
+   {
+      return ir_type == ir_type_dereference_array ||
+             ir_type == ir_type_dereference_record ||
+             ir_type == ir_type_dereference_variable;
+   }
+
+   bool is_jump() const
+   {
+      return ir_type == ir_type_loop_jump ||
+             ir_type == ir_type_return ||
+             ir_type == ir_type_discard;
+   }
+
    /**
     * \name IR instruction downcast functions
     *
@@ -117,45 +143,33 @@ public:
     * Additional downcast functions will be added as needed.
     */
    /*@{*/
-   class ir_rvalue *as_rvalue()
-   {
-      assume(this != NULL);
-      if (ir_type == ir_type_dereference_array ||
-          ir_type == ir_type_dereference_record ||
-          ir_type == ir_type_dereference_variable ||
-          ir_type == ir_type_constant ||
-          ir_type == ir_type_expression ||
-          ir_type == ir_type_swizzle ||
-          ir_type == ir_type_texture)
-         return (class ir_rvalue *) this;
-      return NULL;
-   }
-
-   class ir_dereference *as_dereference()
-   {
-      assume(this != NULL);
-      if (ir_type == ir_type_dereference_array ||
-          ir_type == ir_type_dereference_record ||
-          ir_type == ir_type_dereference_variable)
-         return (class ir_dereference *) this;
-      return NULL;
-   }
-
-   class ir_jump *as_jump()
-   {
-      assume(this != NULL);
-      if (ir_type == ir_type_loop_jump ||
-          ir_type == ir_type_return ||
-          ir_type == ir_type_discard)
-         return (class ir_jump *) this;
-      return NULL;
-   }
+   #define AS_BASE(TYPE)                                \
+   class ir_##TYPE *as_##TYPE()                         \
+   {                                                    \
+      assume(this != NULL);                             \
+      return is_##TYPE() ? (ir_##TYPE *) this : NULL;   \
+   }                                                    \
+   const class ir_##TYPE *as_##TYPE() const             \
+   {                                                    \
+      assume(this != NULL);                             \
+      return is_##TYPE() ? (ir_##TYPE *) this : NULL;   \
+   }
+
+   AS_BASE(rvalue)
+   AS_BASE(dereference)
+   AS_BASE(jump)
+   #undef AS_BASE
 
    #define AS_CHILD(TYPE) \
    class ir_##TYPE * as_##TYPE() \
    { \
       assume(this != NULL);                                         \
       return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL; \
+   }                                                                      \
+   const class ir_##TYPE * as_##TYPE() const                              \
+   {                                                                      \
+      assume(this != NULL);                                               \
+      return ir_type == ir_type_##TYPE ? (const ir_##TYPE *) this : NULL; \
    }
    AS_CHILD(variable)
    AS_CHILD(function)
@@ -183,7 +197,8 @@ public:
     * in particular.  No support for other instruction types (assignments,
     * jumps, calls, etc.) is planned.
     */
-   virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+   virtual bool equals(const ir_instruction *ir,
+                       enum ir_node_type ignore = ir_type_unset) const;
 
 protected:
    ir_instruction(enum ir_node_type t)
@@ -309,6 +324,7 @@ protected:
 enum ir_variable_mode {
    ir_var_auto = 0,     /**< Function local variables and globals. */
    ir_var_uniform,      /**< Variable declared as a uniform. */
+   ir_var_shader_storage,   /**< Variable declared as an ssbo. */
    ir_var_shader_in,
    ir_var_shader_out,
    ir_var_function_in,
@@ -426,11 +442,14 @@ public:
    glsl_interp_qualifier determine_interpolation_mode(bool flat_shade);
 
    /**
-    * Determine whether or not a variable is part of a uniform block.
+    * Determine whether or not a variable is part of a uniform or
+    * shader storage block.
     */
-   inline bool is_in_uniform_block() const
+   inline bool is_in_buffer_block() const
    {
-      return this->data.mode == ir_var_uniform && this->interface_type != NULL;
+      return (this->data.mode == ir_var_uniform ||
+              this->data.mode == ir_var_shader_storage) &&
+             this->interface_type != NULL;
    }
 
    /**
@@ -603,6 +622,7 @@ public:
       unsigned read_only:1;
       unsigned centroid:1;
       unsigned sample:1;
+      unsigned patch:1;
       unsigned invariant:1;
       unsigned precise:1;
 
@@ -1106,6 +1126,21 @@ public:
     * List of ir_function_signature for each overloaded function with this name.
     */
    struct exec_list signatures;
+
+   /**
+    * is this function a subroutine type declaration
+    * e.g. subroutine void type1(float arg1);
+    */
+   bool is_subroutine;
+
+   /**
+    * is this function associated to a subroutine type
+    * e.g. subroutine (type1, type2) function_name { function_body };
+    * would have num_subroutine_types 2,
+    * and pointers to the type1 and type2 types.
+    */
+   int num_subroutine_types;
+   const struct glsl_type **subroutine_types;
 };
 
 inline const char *ir_function_signature::function_name() const
@@ -1300,8 +1335,6 @@ enum ir_expression_operation {
    /*@{*/
    ir_unop_sin,
    ir_unop_cos,
-   ir_unop_sin_reduced,    /**< Reduced range sin. [-pi, pi] */
-   ir_unop_cos_reduced,    /**< Reduced range cos. [-pi, pi] */
    /*@}*/
 
    /**
@@ -1367,6 +1400,7 @@ enum ir_expression_operation {
 
    ir_unop_noise,
 
+   ir_unop_subroutine_to_int,
    /**
     * Interpolate fs input at centroid
     *
@@ -1598,7 +1632,8 @@ public:
     */
    ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2);
 
-   virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+   virtual bool equals(const ir_instruction *ir,
+                       enum ir_node_type ignore = ir_type_unset) const;
 
    virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
 
@@ -1677,7 +1712,18 @@ public:
    ir_call(ir_function_signature *callee,
           ir_dereference_variable *return_deref,
           exec_list *actual_parameters)
-      : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee)
+      : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(NULL), array_idx(NULL)
+   {
+      assert(callee->return_type != NULL);
+      actual_parameters->move_nodes_to(& this->actual_parameters);
+      this->use_builtin = callee->is_builtin();
+   }
+
+   ir_call(ir_function_signature *callee,
+          ir_dereference_variable *return_deref,
+          exec_list *actual_parameters,
+          ir_variable *var, ir_rvalue *array_idx)
+      : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(var), array_idx(array_idx)
    {
       assert(callee->return_type != NULL);
       actual_parameters->move_nodes_to(& this->actual_parameters);
@@ -1725,6 +1771,14 @@ public:
 
    /** Should this call only bind to a built-in function? */
    bool use_builtin;
+
+   /*
+    * ARB_shader_subroutine support -
+    * the subroutine uniform variable and array index
+    * rvalue to be used in the lowering pass later.
+    */
+   ir_variable *sub_var;
+   ir_rvalue *array_idx;
 };
 
 
@@ -1909,7 +1963,8 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+   virtual bool equals(const ir_instruction *ir,
+                       enum ir_node_type ignore = ir_type_unset) const;
 
    /**
     * Return a string representing the ir_texture_opcode.
@@ -2010,7 +2065,8 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+   virtual bool equals(const ir_instruction *ir,
+                       enum ir_node_type ignore = ir_type_unset) const;
 
    bool is_lvalue() const
    {
@@ -2063,7 +2119,8 @@ public:
 
    virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
-   virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+   virtual bool equals(const ir_instruction *ir,
+                       enum ir_node_type ignore = ir_type_unset) const;
 
    /**
     * Get the variable that is ultimately referenced by an r-value
@@ -2109,7 +2166,8 @@ public:
 
    virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
-   virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+   virtual bool equals(const ir_instruction *ir,
+                       enum ir_node_type ignore = ir_type_unset) const;
 
    /**
     * Get the variable that is ultimately referenced by an r-value
@@ -2219,7 +2277,8 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+   virtual bool equals(const ir_instruction *ir,
+                       enum ir_node_type ignore = ir_type_unset) const;
 
    /**
     * Get a particular component of a constant as a specific type
@@ -2378,6 +2437,29 @@ public:
    ir_rvalue *stream;
 };
 
+/**
+ * IR instruction for tessellation control and compute shader barrier.
+ */
+class ir_barrier : public ir_instruction {
+public:
+   ir_barrier()
+      : ir_instruction(ir_type_barrier)
+   {
+   }
+
+   virtual void accept(ir_visitor *v)
+   {
+      v->visit(this);
+   }
+
+   virtual ir_barrier *clone(void *mem_ctx, struct hash_table *) const
+   {
+      return new(mem_ctx) ir_barrier();
+   }
+
+   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+};
+
 /*@}*/
 
 /**