X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fast.h;h=03df6c08b2bf1905abb67fa001c78660d55fcef8;hb=6a660a5f5dad02a6594ea905c511ba3cae6862a5;hp=103146c10473791bb196f06793229a1dc02e6361;hpb=361206771c76d2ea0ef97632404467082688e072;p=mesa.git diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 103146c1047..03df6c08b2b 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -49,24 +49,7 @@ struct YYLTYPE; */ class ast_node { public: - /* Callers of this ralloc-based new need not call delete. It's - * easier to just ralloc_free 'ctx' (or any of its ancestors). */ - static void* operator new(size_t size, void *ctx) - { - void *node; - - node = rzalloc_size(ctx, size); - assert(node != NULL); - - return node; - } - - /* If the user *does* call delete, that's OK, we will just - * ralloc_free in that case. */ - static void operator delete(void *table) - { - ralloc_free(table); - } + DECLARE_RALLOC_CXX_OPERATORS(ast_node); /** * Print an AST node in something approximating the original GLSL code @@ -79,6 +62,8 @@ public: virtual ir_rvalue *hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); + virtual bool has_sequence_subexpression() const; + /** * Retrieve the source location of an AST node * @@ -92,10 +77,10 @@ public: struct YYLTYPE locp; locp.source = this->location.source; - locp.first_line = this->location.line; - locp.first_column = this->location.column; - locp.last_line = locp.first_line; - locp.last_column = locp.first_column; + locp.first_line = this->location.first_line; + locp.first_column = this->location.first_column; + locp.last_line = this->location.last_line; + locp.last_column = this->location.last_column; return locp; } @@ -108,17 +93,35 @@ public: void set_location(const struct YYLTYPE &locp) { this->location.source = locp.source; - this->location.line = locp.first_line; - this->location.column = locp.first_column; + this->location.first_line = locp.first_line; + this->location.first_column = locp.first_column; + this->location.last_line = locp.last_line; + this->location.last_column = locp.last_column; + } + + /** + * Set the source location range of an AST node using two location nodes + * + * \sa ast_node::set_location + */ + void set_location_range(const struct YYLTYPE &begin, const struct YYLTYPE &end) + { + this->location.source = begin.source; + this->location.first_line = begin.first_line; + this->location.last_line = end.last_line; + this->location.first_column = begin.first_column; + this->location.last_column = end.last_column; } /** * Source location of the AST node. */ struct { - unsigned source; /**< GLSL source number. */ - unsigned line; /**< Line number within the source string. */ - unsigned column; /**< Column in the line. */ + unsigned source; /**< GLSL source number. */ + unsigned first_line; /**< First line number within the source string. */ + unsigned first_column; /**< First column in the first line. */ + unsigned last_line; /**< Last line number within the source string. */ + unsigned last_column; /**< Last column in the last line. */ } location; exec_node link; @@ -180,6 +183,7 @@ enum ast_operators { ast_post_dec, ast_field_selection, ast_array_index, + ast_unsized_array_dim, ast_function_call, @@ -188,8 +192,10 @@ enum ast_operators { ast_uint_constant, ast_float_constant, ast_bool_constant, + ast_double_constant, - ast_sequence + ast_sequence, + ast_aggregate }; /** @@ -215,6 +221,15 @@ public: virtual ir_rvalue *hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); + virtual void hir_no_rvalue(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + virtual bool has_sequence_subexpression() const; + + ir_rvalue *do_hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state, + bool needs_rvalue); + virtual void print(void) const; enum ast_operators oper; @@ -227,6 +242,7 @@ public: float float_constant; unsigned uint_constant; int bool_constant; + double double_constant; } primary_expression; @@ -285,13 +301,111 @@ public: virtual ir_rvalue *hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); + virtual void hir_no_rvalue(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + virtual bool has_sequence_subexpression() const; + private: /** * Is this function call actually a constructor? */ bool cons; + ir_rvalue * + handle_method(exec_list *instructions, + struct _mesa_glsl_parse_state *state); +}; + +class ast_subroutine_list : public ast_node +{ +public: + virtual void print(void) const; + exec_list declarations; +}; + +class ast_array_specifier : public ast_node { +public: + ast_array_specifier(const struct YYLTYPE &locp, ast_expression *dim) + { + set_location(locp); + array_dimensions.push_tail(&dim->link); + } + + void add_dimension(ast_expression *dim) + { + array_dimensions.push_tail(&dim->link); + } + + bool is_single_dimension() const + { + return this->array_dimensions.tail_pred->prev != NULL && + this->array_dimensions.tail_pred->prev->is_head_sentinel(); + } + + virtual void print(void) const; + + /* This list contains objects of type ast_node containing the + * array dimensions in outermost-to-innermost order. + */ + exec_list array_dimensions; +}; + +class ast_layout_expression : public ast_node { +public: + ast_layout_expression(const struct YYLTYPE &locp, ast_expression *expr) + { + set_location(locp); + layout_const_expressions.push_tail(&expr->link); + } + + bool process_qualifier_constant(struct _mesa_glsl_parse_state *state, + const char *qual_indentifier, + unsigned *value, bool can_be_zero); + + void merge_qualifier(ast_layout_expression *l_expr) + { + layout_const_expressions.append_list(&l_expr->layout_const_expressions); + } + + exec_list layout_const_expressions; }; +/** + * C-style aggregate initialization class + * + * Represents C-style initializers of vectors, matrices, arrays, and + * structures. E.g., vec3 pos = {1.0, 0.0, -1.0} is equivalent to + * vec3 pos = vec3(1.0, 0.0, -1.0). + * + * Specified in GLSL 4.20 and GL_ARB_shading_language_420pack. + * + * \sa _mesa_ast_set_aggregate_type + */ +class ast_aggregate_initializer : public ast_expression { +public: + ast_aggregate_initializer() + : ast_expression(ast_aggregate, NULL, NULL, NULL), + constructor_type(NULL) + { + /* empty */ + } + + /** + * glsl_type of the aggregate, which is inferred from the LHS of whatever + * the aggregate is being used to initialize. This can't be inferred at + * parse time (since the parser deals with ast_type_specifiers, not + * glsl_types), so the parser leaves it NULL. However, the ast-to-hir + * conversion code makes sure to fill it in with the appropriate type + * before hir() is called. + */ + const glsl_type *constructor_type; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + virtual void hir_no_rvalue(exec_list *instructions, + struct _mesa_glsl_parse_state *state); +}; /** * Number of possible operators for an ast_expression @@ -317,14 +431,14 @@ public: class ast_declaration : public ast_node { public: - ast_declaration(const char *identifier, int is_array, ast_expression *array_size, - ast_expression *initializer); + ast_declaration(const char *identifier, + ast_array_specifier *array_specifier, + ast_expression *initializer); virtual void print(void) const; const char *identifier; - - int is_array; - ast_expression *array_size; + + ast_array_specifier *array_specifier; ast_expression *initializer; }; @@ -338,35 +452,23 @@ enum { }; struct ast_type_qualifier { - /* Callers of this ralloc-based new need not call delete. It's - * easier to just ralloc_free 'ctx' (or any of its ancestors). */ - static void* operator new(size_t size, void *ctx) - { - void *node; - - node = rzalloc_size(ctx, size); - assert(node != NULL); - - return node; - } - - /* If the user *does* call delete, that's OK, we will just - * ralloc_free in that case. */ - static void operator delete(void *table) - { - ralloc_free(table); - } + DECLARE_RALLOC_CXX_OPERATORS(ast_type_qualifier); union { struct { unsigned invariant:1; + unsigned precise:1; unsigned constant:1; unsigned attribute:1; unsigned varying:1; unsigned in:1; unsigned out:1; unsigned centroid:1; + unsigned sample:1; + unsigned patch:1; unsigned uniform:1; + unsigned buffer:1; + unsigned shared_storage:1; unsigned smooth:1; unsigned flat:1; unsigned noperspective:1; @@ -388,6 +490,18 @@ struct ast_type_qualifier { */ unsigned explicit_index:1; + /** + * Flag set if GL_ARB_shading_language_420pack "binding" layout + * qualifier is used. + */ + unsigned explicit_binding:1; + + /** + * Flag set if GL_ARB_shader_atomic counter "offset" layout + * qualifier is used. + */ + unsigned explicit_offset:1; + /** \name Layout qualifiers for GL_AMD_conservative_depth */ /** \{ */ unsigned depth_any:1; @@ -399,39 +513,178 @@ struct ast_type_qualifier { /** \name Layout qualifiers for GL_ARB_uniform_buffer_object */ /** \{ */ unsigned std140:1; + unsigned std430:1; unsigned shared:1; unsigned packed:1; unsigned column_major:1; unsigned row_major:1; /** \} */ + + /** \name Layout qualifiers for GLSL 1.50 geometry shaders */ + /** \{ */ + unsigned prim_type:1; + unsigned max_vertices:1; + /** \} */ + + /** + * local_size_{x,y,z} flags for compute shaders. Bit 0 represents + * local_size_x, and so on. + */ + unsigned local_size:3; + + /** \name Layout and memory qualifiers for ARB_shader_image_load_store. */ + /** \{ */ + unsigned early_fragment_tests:1; + unsigned explicit_image_format:1; + unsigned coherent:1; + unsigned _volatile:1; + unsigned restrict_flag:1; + unsigned read_only:1; /**< "readonly" qualifier. */ + unsigned write_only:1; /**< "writeonly" qualifier. */ + /** \} */ + + /** \name Layout qualifiers for GL_ARB_gpu_shader5 */ + /** \{ */ + unsigned invocations:1; + unsigned stream:1; /**< Has stream value assigned */ + unsigned explicit_stream:1; /**< stream value assigned explicitly by shader code */ + /** \} */ + + /** \name Layout qualifiers for GL_ARB_tessellation_shader */ + /** \{ */ + /* tess eval input layout */ + /* gs prim_type reused for primitive mode */ + unsigned vertex_spacing:1; + unsigned ordering:1; + unsigned point_mode:1; + /* tess control output layout */ + unsigned vertices:1; + /** \} */ + + /** \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 */ + /** \} */ } /** \brief Set of flags, accessed by name. */ q; /** \brief Set of flags, accessed as a bitmask. */ - unsigned i; + uint64_t i; } flags; + /** Precision of the type (highp/medium/lowp). */ + unsigned precision:2; + + /** Geometry shader invocations for GL_ARB_gpu_shader5. */ + ast_layout_expression *invocations; + /** * Location specified via GL_ARB_explicit_attrib_location layout * * \note * This field is only valid if \c explicit_location is set. */ - int location; + ast_expression *location; /** * Index specified via GL_ARB_explicit_attrib_location layout * * \note * This field is only valid if \c explicit_index is set. */ - int index; + ast_expression *index; + + /** Maximum output vertices in GLSL 1.50 geometry shaders. */ + ast_layout_expression *max_vertices; + + /** Stream in GLSL 1.50 geometry shaders. */ + ast_expression *stream; + + /** + * Input or output primitive type in GLSL 1.50 geometry shaders + * and tessellation shaders. + */ + GLenum prim_type; + + /** + * Binding specified via GL_ARB_shading_language_420pack's "binding" keyword. + * + * \note + * This field is only valid if \c explicit_binding is set. + */ + ast_expression *binding; + + /** + * Offset specified via GL_ARB_shader_atomic_counter's "offset" + * keyword. + * + * \note + * This field is only valid if \c explicit_offset is set. + */ + ast_expression *offset; + + /** + * Local size specified via GL_ARB_compute_shader's "local_size_{x,y,z}" + * layout qualifier. Element i of this array is only valid if + * flags.q.local_size & (1 << i) is set. + */ + ast_layout_expression *local_size[3]; + + /** Tessellation evaluation shader: vertex spacing (equal, fractional even/odd) */ + GLenum vertex_spacing; + + /** Tessellation evaluation shader: vertex ordering (CW or CCW) */ + GLenum ordering; + + /** Tessellation evaluation shader: point mode */ + bool point_mode; + + /** Tessellation control shader: number of output vertices */ + ast_layout_expression *vertices; + + /** + * Image format specified with an ARB_shader_image_load_store + * layout qualifier. + * + * \note + * This field is only valid if \c explicit_image_format is set. + */ + GLenum image_format; + + /** + * Base type of the data read from or written to this image. Only + * the following enumerants are allowed: GLSL_TYPE_UINT, + * GLSL_TYPE_INT, GLSL_TYPE_FLOAT. + * + * \note + * This field is only valid if \c explicit_image_format is set. + */ + 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. */ bool has_interpolation() const; + /** + * Return whether a layout qualifier is present. + */ + bool has_layout() const; + + /** + * Return whether a storage qualifier is present. + */ + bool has_storage() const; + + /** + * Return whether an auxiliary storage qualifier is present. + */ + bool has_auxiliary_storage() const; + /** * \brief Return string representation of interpolation qualifier. * @@ -446,7 +699,20 @@ struct ast_type_qualifier { bool merge_qualifier(YYLTYPE *loc, _mesa_glsl_parse_state *state, - ast_type_qualifier q); + const ast_type_qualifier &q, + bool is_single_layout_merge); + + bool merge_out_qualifier(YYLTYPE *loc, + _mesa_glsl_parse_state *state, + const ast_type_qualifier &q, + ast_node* &node, bool create_node); + + bool merge_in_qualifier(YYLTYPE *loc, + _mesa_glsl_parse_state *state, + const ast_type_qualifier &q, + ast_node* &node, bool create_node); + + ast_subroutine_list *subroutine_list; }; class ast_declarator_list; @@ -461,8 +727,10 @@ public: struct _mesa_glsl_parse_state *state); const char *name; + ast_type_qualifier *layout; /* List of ast_declarator_list * */ exec_list declarations; + bool is_declaration; }; @@ -471,18 +739,16 @@ 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), - is_array(false), array_size(NULL), precision(ast_precision_none), - is_precision_statement(false) + : type_name(name), structure(NULL), array_specifier(NULL), + default_precision(ast_precision_none) { /* empty */ } /** Construct a type specifier from a structure definition */ ast_type_specifier(ast_struct_specifier *s) - : type_name(s->name), structure(s), - is_array(false), array_size(NULL), precision(ast_precision_none), - is_precision_statement(false) + : type_name(s->name), structure(s), array_specifier(NULL), + default_precision(ast_precision_none) { /* empty */ } @@ -498,19 +764,25 @@ public: const char *type_name; ast_struct_specifier *structure; - int is_array; - ast_expression *array_size; - - unsigned precision:2; + ast_array_specifier *array_specifier; - bool is_precision_statement; + /** For precision statements, this is the given precision; otherwise none. */ + unsigned default_precision:2; }; class ast_fully_specified_type : public ast_node { public: virtual void print(void) const; - bool has_qualifiers() const; + bool has_qualifiers(_mesa_glsl_parse_state *state) const; + + ast_fully_specified_type() : qualifier(), specifier(NULL) + { + } + + const struct glsl_type *glsl_type(const char **name, + struct _mesa_glsl_parse_state *state) + const; ast_type_qualifier qualifier; ast_type_specifier *specifier; @@ -530,19 +802,11 @@ public: exec_list declarations; /** - * Special flag for vertex shader "invariant" declarations. - * - * Vertex shaders can contain "invariant" variable redeclarations that do - * not include a type. For example, "invariant gl_Position;". This flag - * is used to note these cases when no type is specified. + * Flags for redeclarations. In these cases, no type is specified, to + * `type` is allowed to be NULL. In all other cases, this would be an error. */ - int invariant; - - /** - * Flag indicating that these declarators are in a uniform block, - * allowing UBO type qualifiers. - */ - bool ubo_qualifiers_valid; + int invariant; /** < `invariant` redeclaration */ + int precise; /** < `precise` redeclaration */ }; @@ -551,8 +815,7 @@ public: ast_parameter_declarator() : type(NULL), identifier(NULL), - is_array(false), - array_size(NULL), + array_specifier(NULL), formal_parameter(false), is_void(false) { @@ -566,8 +829,7 @@ public: ast_fully_specified_type *type; const char *identifier; - int is_array; - ast_expression *array_size; + ast_array_specifier *array_specifier; static void parameters_to_hir(exec_list *ast_parameters, bool formal, exec_list *ir_parameters, @@ -765,14 +1027,13 @@ public: ast_node *body; -private: /** * Generate IR from the condition of a loop * * This is factored out of ::hir because some loops have the condition * test at the top (for and while), and others have it at the end (do-while). */ - void condition_to_hir(class ir_loop *, struct _mesa_glsl_parse_state *); + void condition_to_hir(exec_list *, struct _mesa_glsl_parse_state *); }; @@ -797,6 +1058,10 @@ public: class ast_function_definition : public ast_node { public: + ast_function_definition() : prototype(NULL), body(NULL) + { + } + virtual void print(void) const; virtual ir_rvalue *hir(exec_list *instructions, @@ -809,12 +1074,11 @@ public: class ast_interface_block : public ast_node { public: ast_interface_block(ast_type_qualifier layout, - const char *instance_name, - ast_expression *array_size) + const char *instance_name, + ast_array_specifier *array_specifier) : layout(layout), block_name(NULL), instance_name(instance_name), - array_size(array_size) + array_specifier(array_specifier) { - /* empty */ } virtual ir_rvalue *hir(exec_list *instructions, @@ -837,14 +1101,74 @@ public: /** * Declared array size of the block instance * - * If the block is not declared as an array, this field will be \c NULL. - * - * \note - * A block can only be an array if it also has an instance name. If this - * field is not \c NULL, ::instance_name must also not be \c NULL. + * If the block is not declared as an array or if the block instance array + * is unsized, this field will be \c NULL. */ - ast_expression *array_size; + ast_array_specifier *array_specifier; }; + + +/** + * AST node representing a declaration of the output layout for tessellation + * control shaders. + */ +class ast_tcs_output_layout : public ast_node +{ +public: + ast_tcs_output_layout(const struct YYLTYPE &locp) + { + set_location(locp); + } + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); +}; + + +/** + * AST node representing a declaration of the input layout for geometry + * shaders. + */ +class ast_gs_input_layout : public ast_node +{ +public: + ast_gs_input_layout(const struct YYLTYPE &locp, GLenum prim_type) + : prim_type(prim_type) + { + set_location(locp); + } + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + +private: + const GLenum prim_type; +}; + + +/** + * AST node representing a decalaration of the input layout for compute + * shaders. + */ +class ast_cs_input_layout : public ast_node +{ +public: + ast_cs_input_layout(const struct YYLTYPE &locp, + ast_layout_expression *const *local_size) + { + for (int i = 0; i < 3; i++) { + this->local_size[i] = local_size[i]; + } + set_location(locp); + } + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + +private: + ast_layout_expression *local_size[3]; +}; + /*@}*/ extern void @@ -861,6 +1185,10 @@ _mesa_ast_array_index_to_hir(void *mem_ctx, ir_rvalue *array, ir_rvalue *idx, YYLTYPE &loc, YYLTYPE &idx_loc); +extern void +_mesa_ast_set_aggregate_type(const glsl_type *type, + ast_expression *expr); + void emit_function(_mesa_glsl_parse_state *state, ir_function *f); @@ -868,4 +1196,9 @@ extern void check_builtin_array_max_size(const char *name, unsigned size, YYLTYPE loc, struct _mesa_glsl_parse_state *state); +extern void _mesa_ast_process_interface_block(YYLTYPE *locp, + _mesa_glsl_parse_state *state, + ast_interface_block *const block, + const struct ast_type_qualifier &q); + #endif /* AST_H */