glsl: fix the type of ir_constant_data::u16
[mesa.git] / src / compiler / glsl / ast.h
index 9aa5bb99f49a8fbbc0f75b960681563d9be574ab..3a960c2ff327306b924657ffdad22569fc07e5aa 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
-#pragma once
 #ifndef AST_H
 #define AST_H
 
 #include "list.h"
 #include "glsl_parser_extras.h"
+#include "compiler/glsl_types.h"
+#include "util/bitset.h"
 
 struct _mesa_glsl_parse_state;
 
@@ -49,7 +50,7 @@ struct YYLTYPE;
  */
 class ast_node {
 public:
-   DECLARE_RALLOC_CXX_OPERATORS(ast_node);
+   DECLARE_LINEAR_ZALLOC_CXX_OPERATORS(ast_node);
 
    /**
     * Print an AST node in something approximating the original GLSL code
@@ -76,6 +77,7 @@ public:
    {
       struct YYLTYPE locp;
 
+      locp.path = this->location.path;
       locp.source = this->location.source;
       locp.first_line = this->location.first_line;
       locp.first_column = this->location.first_column;
@@ -92,6 +94,7 @@ public:
     */
    void set_location(const struct YYLTYPE &locp)
    {
+      this->location.path = locp.path;
       this->location.source = locp.source;
       this->location.first_line = locp.first_line;
       this->location.first_column = locp.first_column;
@@ -106,6 +109,7 @@ public:
     */
    void set_location_range(const struct YYLTYPE &begin, const struct YYLTYPE &end)
    {
+      this->location.path = begin.path;
       this->location.source = begin.source;
       this->location.first_line = begin.first_line;
       this->location.last_line = end.last_line;
@@ -117,6 +121,7 @@ public:
     * Source location of the AST node.
     */
    struct {
+      char *path;               /**< GLSL shader include path. */
       unsigned source;          /**< GLSL source number. */
       unsigned first_line;      /**< First line number within the source string. */
       unsigned first_column;    /**< First column in the first line. */
@@ -126,6 +131,8 @@ public:
 
    exec_node link;
 
+   virtual void set_is_lhs(bool);
+
 protected:
    /**
     * The only constructor is protected so that only derived class objects can
@@ -193,9 +200,20 @@ enum ast_operators {
    ast_float_constant,
    ast_bool_constant,
    ast_double_constant,
+   ast_int64_constant,
+   ast_uint64_constant,
 
    ast_sequence,
    ast_aggregate
+
+   /**
+    * Number of possible operators for an ast_expression
+    *
+    * This is done as a define instead of as an additional value in the enum so
+    * that the compiler won't generate spurious messages like "warning:
+    * enumeration value ‘ast_num_operators’ not handled in switch"
+    */
+   #define AST_NUM_OPERATORS (ast_aggregate + 1)
 };
 
 /**
@@ -214,6 +232,7 @@ public:
       subexpressions[2] = NULL;
       primary_expression.identifier = identifier;
       this->non_lvalue_description = NULL;
+      this->is_lhs = false;
    }
 
    static const char *operator_string(enum ast_operators op);
@@ -243,6 +262,8 @@ public:
       unsigned uint_constant;
       int bool_constant;
       double double_constant;
+      uint64_t uint64_constant;
+      int64_t int64_constant;
    } primary_expression;
 
 
@@ -263,6 +284,11 @@ public:
     * This pointer may be \c NULL.
     */
    const char *non_lvalue_description;
+
+   void set_is_lhs(bool new_value);
+
+private:
+   bool is_lhs;
 };
 
 class ast_expression_bin : public ast_expression {
@@ -338,8 +364,8 @@ public:
 
    bool is_single_dimension() const
    {
-      return this->array_dimensions.tail_pred->prev != NULL &&
-             this->array_dimensions.tail_pred->prev->is_head_sentinel();
+      return this->array_dimensions.get_tail_raw()->prev != NULL &&
+             this->array_dimensions.get_tail_raw()->prev->is_head_sentinel();
    }
 
    virtual void print(void) const;
@@ -407,15 +433,6 @@ public:
                               struct _mesa_glsl_parse_state *state);
 };
 
-/**
- * Number of possible operators for an ast_expression
- *
- * This is done as a define instead of as an additional value in the enum so
- * that the compiler won't generate spurious messages like "warning:
- * enumeration value ‘ast_num_operators’ not handled in switch"
- */
-#define AST_NUM_OPERATORS (ast_sequence + 1)
-
 
 class ast_compound_statement : public ast_node {
 public:
@@ -451,10 +468,25 @@ enum {
    ast_precision_low
 };
 
+enum {
+   ast_depth_none = 0, /**< Absence of depth qualifier. */
+   ast_depth_any,
+   ast_depth_greater,
+   ast_depth_less,
+   ast_depth_unchanged
+};
+
 struct ast_type_qualifier {
    DECLARE_RALLOC_CXX_OPERATORS(ast_type_qualifier);
+   /* Note: this bitset needs to have at least as many bits as the 'q'
+    * struct has flags, below.  Previously, the size was 128 instead of 96.
+    * But an apparent bug in GCC 5.4.0 causes bad SSE code generation
+    * elsewhere, leading to a crash.  96 bits works around the issue.
+    * See https://bugs.freedesktop.org/show_bug.cgi?id=105497
+    */
+   DECLARE_BITSET_T(bitset_t, 96);
 
-   union {
+   union flags {
       struct {
         unsigned invariant:1;
          unsigned precise:1;
@@ -479,6 +511,12 @@ struct ast_type_qualifier {
         unsigned pixel_center_integer:1;
         /*@}*/
 
+         /**
+          * Flag set if GL_ARB_enhanced_layouts "align" layout qualifier is
+          * used.
+          */
+         unsigned explicit_align:1;
+
         /**
          * Flag set if GL_ARB_explicit_attrib_location "location" layout
          * qualifier is used.
@@ -490,6 +528,12 @@ struct ast_type_qualifier {
          */
         unsigned explicit_index:1;
 
+        /**
+         * Flag set if GL_ARB_enhanced_layouts "component" layout
+         * qualifier is used.
+         */
+        unsigned explicit_component:1;
+
          /**
           * Flag set if GL_ARB_shading_language_420pack "binding" layout
           * qualifier is used.
@@ -504,10 +548,7 @@ struct ast_type_qualifier {
 
          /** \name Layout qualifiers for GL_AMD_conservative_depth */
          /** \{ */
-         unsigned depth_any:1;
-         unsigned depth_greater:1;
-         unsigned depth_less:1;
-         unsigned depth_unchanged:1;
+         unsigned depth_type:1;
          /** \} */
 
         /** \name Layout qualifiers for GL_ARB_uniform_buffer_object */
@@ -532,6 +573,11 @@ struct ast_type_qualifier {
           */
          unsigned local_size:3;
 
+        /** \name Layout qualifiers for ARB_compute_variable_group_size. */
+        /** \{ */
+        unsigned local_size_variable:1;
+        /** \} */
+
         /** \name Layout and memory qualifiers for ARB_shader_image_load_store. */
         /** \{ */
         unsigned early_fragment_tests:1;
@@ -550,6 +596,15 @@ struct ast_type_qualifier {
          unsigned explicit_stream:1; /**< stream value assigned explicitly by shader code */
          /** \} */
 
+         /** \name Layout qualifiers for GL_ARB_enhanced_layouts */
+         /** \{ */
+         unsigned explicit_xfb_offset:1; /**< xfb_offset value assigned explicitly by shader code */
+         unsigned xfb_buffer:1; /**< Has xfb_buffer value assigned  */
+         unsigned explicit_xfb_buffer:1; /**< xfb_buffer value assigned explicitly by shader code */
+         unsigned xfb_stride:1; /**< Is xfb_stride value yet to be merged with global values  */
+         unsigned explicit_xfb_stride:1; /**< xfb_stride value assigned explicitly by shader code */
+         /** \} */
+
         /** \name Layout qualifiers for GL_ARB_tessellation_shader */
         /** \{ */
         /* tess eval input layout */
@@ -564,19 +619,75 @@ struct ast_type_qualifier {
          /** \name Qualifiers for GL_ARB_shader_subroutine */
         /** \{ */
          unsigned subroutine:1;  /**< Is this marked 'subroutine' */
-         unsigned subroutine_def:1; /**< Is this marked 'subroutine' with a list of types */
         /** \} */
+
+         /** \name Qualifiers for GL_KHR_blend_equation_advanced */
+         /** \{ */
+         unsigned blend_support:1; /**< Are there any blend_support_ qualifiers */
+         /** \} */
+
+         /**
+          * Flag set if GL_ARB_post_depth_coverage layout qualifier is used.
+          */
+         unsigned post_depth_coverage:1;
+
+         /**
+          * Flags for the layout qualifers added by ARB_fragment_shader_interlock
+          */
+
+         unsigned pixel_interlock_ordered:1;
+         unsigned pixel_interlock_unordered:1;
+         unsigned sample_interlock_ordered:1;
+         unsigned sample_interlock_unordered:1;
+
+         /**
+          * Flag set if GL_INTEL_conservartive_rasterization layout qualifier
+          * is used.
+          */
+         unsigned inner_coverage:1;
+
+         /** \name Layout qualifiers for GL_ARB_bindless_texture */
+         /** \{ */
+         unsigned bindless_sampler:1;
+         unsigned bindless_image:1;
+         unsigned bound_sampler:1;
+         unsigned bound_image:1;
+         /** \} */
+
+         /** \name Layout qualifiers for GL_EXT_shader_framebuffer_fetch_non_coherent */
+         /** \{ */
+         unsigned non_coherent:1;
+         /** \} */
+
+         /** \name Layout qualifiers for NV_compute_shader_derivatives */
+         /** \{ */
+         unsigned derivative_group:1;
+         /** \} */
+
+         /**
+          * Flag set if GL_NV_viewport_array2 viewport_relative layout
+          * qualifier is used.
+          */
+         unsigned viewport_relative:1;
       }
       /** \brief Set of flags, accessed by name. */
       q;
 
       /** \brief Set of flags, accessed as a bitmask. */
-      uint64_t i;
+      bitset_t i;
    } flags;
 
    /** Precision of the type (highp/medium/lowp). */
    unsigned precision:2;
 
+   /** Type of layout qualifiers for GL_AMD_conservative_depth. */
+   unsigned depth_type:3;
+
+   /**
+    * Alignment specified via GL_ARB_enhanced_layouts "align" layout qualifier
+    */
+   ast_expression *align;
+
    /** Geometry shader invocations for GL_ARB_gpu_shader5. */
    ast_layout_expression *invocations;
 
@@ -595,12 +706,29 @@ struct ast_type_qualifier {
     */
    ast_expression *index;
 
+   /**
+    * Component specified via GL_ARB_enhaced_layouts
+    *
+    * \note
+    * This field is only valid if \c explicit_component is set.
+    */
+   ast_expression *component;
+
    /** Maximum output vertices in GLSL 1.50 geometry shaders. */
    ast_layout_expression *max_vertices;
 
    /** Stream in GLSL 1.50 geometry shaders. */
    ast_expression *stream;
 
+   /** xfb_buffer specified via the GL_ARB_enhanced_layouts keyword. */
+   ast_expression *xfb_buffer;
+
+   /** xfb_stride specified via the GL_ARB_enhanced_layouts keyword. */
+   ast_expression *xfb_stride;
+
+   /** global xfb_stride values for each buffer */
+   ast_layout_expression *out_xfb_stride[MAX_FEEDBACK_BUFFERS];
+
    /**
     * Input or output primitive type in GLSL 1.50 geometry shaders
     * and tessellation shaders.
@@ -616,8 +744,9 @@ struct ast_type_qualifier {
    ast_expression *binding;
 
    /**
-    * Offset specified via GL_ARB_shader_atomic_counter's "offset"
-    * keyword.
+    * Offset specified via GL_ARB_shader_atomic_counter's or
+    * GL_ARB_enhanced_layouts "offset" keyword, or by GL_ARB_enhanced_layouts
+    * "xfb_offset" keyword.
     *
     * \note
     * This field is only valid if \c explicit_offset is set.
@@ -632,7 +761,7 @@ struct ast_type_qualifier {
    ast_layout_expression *local_size[3];
 
    /** Tessellation evaluation shader: vertex spacing (equal, fractional even/odd) */
-   GLenum vertex_spacing;
+   enum gl_tess_spacing vertex_spacing;
 
    /** Tessellation evaluation shader: vertex ordering (CW or CCW) */
    GLenum ordering;
@@ -650,7 +779,13 @@ struct ast_type_qualifier {
     * \note
     * This field is only valid if \c explicit_image_format is set.
     */
-   GLenum image_format;
+   enum pipe_format image_format;
+
+   /**
+    * Arrangement of invocations used to calculate derivatives in a compute
+    * shader.  From NV_compute_shader_derivatives.
+    */
+   enum gl_derivative_group derivative_group;
 
    /**
     * Base type of the data read from or written to this image.  Only
@@ -662,9 +797,6 @@ struct ast_type_qualifier {
     */
    glsl_base_type image_base_type;
 
-   /** Flag to know if this represents a default value for a qualifier */
-   bool is_default_qualifier;
-
    /**
     * Return true if and only if an interpolation qualifier is present.
     */
@@ -685,20 +817,58 @@ struct ast_type_qualifier {
     */
    bool has_auxiliary_storage() const;
 
+   /**
+    * Return true if and only if a memory qualifier is present.
+    */
+   bool has_memory() const;
+
+   /**
+    * Return true if the qualifier is a subroutine declaration.
+    */
+   bool is_subroutine_decl() const;
+
    bool merge_qualifier(YYLTYPE *loc,
                        _mesa_glsl_parse_state *state,
                         const ast_type_qualifier &q,
-                        bool is_single_layout_merge);
+                        bool is_single_layout_merge,
+                        bool is_multiple_layouts_merge = false);
+
+   /**
+    * Validate current qualifier against the global out one.
+    */
+   bool validate_out_qualifier(YYLTYPE *loc,
+                               _mesa_glsl_parse_state *state);
 
-   bool merge_out_qualifier(YYLTYPE *loc,
-                           _mesa_glsl_parse_state *state,
-                           const ast_type_qualifier &q,
-                           ast_node* &node, bool create_node);
+   /**
+    * Merge current qualifier into the global out one.
+    */
+   bool merge_into_out_qualifier(YYLTYPE *loc,
+                                 _mesa_glsl_parse_state *state,
+                                 ast_node* &node);
 
-   bool merge_in_qualifier(YYLTYPE *loc,
-                           _mesa_glsl_parse_state *state,
-                           const ast_type_qualifier &q,
-                           ast_node* &node, bool create_node);
+   /**
+    * Validate current qualifier against the global in one.
+    */
+   bool validate_in_qualifier(YYLTYPE *loc,
+                              _mesa_glsl_parse_state *state);
+
+   /**
+    * Merge current qualifier into the global in one.
+    */
+   bool merge_into_in_qualifier(YYLTYPE *loc,
+                                _mesa_glsl_parse_state *state,
+                                ast_node* &node);
+
+   /**
+    * Push pending layout qualifiers to the global values.
+    */
+   bool push_to_global(YYLTYPE *loc,
+                       _mesa_glsl_parse_state *state);
+
+   bool validate_flags(YYLTYPE *loc,
+                       _mesa_glsl_parse_state *state,
+                       const ast_type_qualifier &allowed_flags,
+                       const char *message, const char *name);
 
    ast_subroutine_list *subroutine_list;
 };
@@ -708,7 +878,7 @@ class ast_declarator_list;
 class ast_struct_specifier : public ast_node {
 public:
    ast_struct_specifier(const char *identifier,
-                       ast_declarator_list *declarator_list);
+                        ast_declarator_list *declarator_list);
    virtual void print(void) const;
 
    virtual ir_rvalue *hir(exec_list *instructions,
@@ -719,6 +889,7 @@ public:
    /* List of ast_declarator_list * */
    exec_list declarations;
    bool is_declaration;
+   const glsl_type *type;
 };
 
 
@@ -727,7 +898,7 @@ class ast_type_specifier : public ast_node {
 public:
    /** Construct a type specifier from a type name */
    ast_type_specifier(const char *name) 
-      : type_name(name), structure(NULL), array_specifier(NULL),
+      : type(NULL), type_name(name), structure(NULL), array_specifier(NULL),
        default_precision(ast_precision_none)
    {
       /* empty */
@@ -735,12 +906,19 @@ public:
 
    /** Construct a type specifier from a structure definition */
    ast_type_specifier(ast_struct_specifier *s)
-      : type_name(s->name), structure(s), array_specifier(NULL),
+      : type(NULL), type_name(s->name), structure(s), array_specifier(NULL),
        default_precision(ast_precision_none)
    {
       /* empty */
    }
 
+   ast_type_specifier(const glsl_type *t)
+      : type(t), type_name(t->name), structure(NULL), array_specifier(NULL),
+        default_precision(ast_precision_none)
+   {
+      /* empty */
+   }
+
    const struct glsl_type *glsl_type(const char **name,
                                     struct _mesa_glsl_parse_state *state)
       const;
@@ -749,6 +927,7 @@ public:
 
    ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
 
+   const struct glsl_type *type;
    const char *type_name;
    ast_struct_specifier *structure;
 
@@ -1044,6 +1223,16 @@ public:
 };
 
 
+class ast_demote_statement : public ast_node {
+public:
+   ast_demote_statement(void) {}
+   virtual void print(void) const;
+
+   virtual ir_rvalue *hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state);
+};
+
+
 class ast_function_definition : public ast_node {
 public:
    ast_function_definition() : prototype(NULL), body(NULL)
@@ -1061,10 +1250,9 @@ public:
 
 class ast_interface_block : public ast_node {
 public:
-   ast_interface_block(ast_type_qualifier layout,
-                       const char *instance_name,
+   ast_interface_block(const char *instance_name,
                        ast_array_specifier *array_specifier)
-   : layout(layout), block_name(NULL), instance_name(instance_name),
+   : block_name(NULL), instance_name(instance_name),
      array_specifier(array_specifier)
    {
    }
@@ -1072,6 +1260,7 @@ public:
    virtual ir_rvalue *hir(exec_list *instructions,
                          struct _mesa_glsl_parse_state *state);
 
+   ast_type_qualifier default_layout;
    ast_type_qualifier layout;
    const char *block_name;
 
@@ -1157,6 +1346,20 @@ private:
    ast_layout_expression *local_size[3];
 };
 
+class ast_warnings_toggle : public ast_node {
+public:
+   ast_warnings_toggle(bool _enable)
+      : enable(_enable)
+   {
+      /* empty */
+   }
+
+   virtual ir_rvalue *hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state);
+
+private:
+   bool enable;
+};
 /*@}*/
 
 extern void
@@ -1189,4 +1392,10 @@ extern void _mesa_ast_process_interface_block(YYLTYPE *locp,
                                               ast_interface_block *const block,
                                               const struct ast_type_qualifier &q);
 
+extern bool
+process_qualifier_constant(struct _mesa_glsl_parse_state *state,
+                           YYLTYPE *loc,
+                           const char *qual_indentifier,
+                           ast_expression *const_expression,
+                           unsigned *value);
 #endif /* AST_H */