diff options
Diffstat (limited to 'mesalib')
-rw-r--r-- | mesalib/src/glsl/ast.h | 1472 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 161 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_type.cpp | 257 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.cpp | 10652 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.h | 597 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.ypp | 3288 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.cpp | 1574 | ||||
-rw-r--r-- | mesalib/src/glsl/loop_analysis.cpp | 997 | ||||
-rw-r--r-- | mesalib/src/glsl/loop_analysis.h | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/context.c | 3806 | ||||
-rw-r--r-- | mesalib/src/mesa/main/mtypes.h | 6702 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shaderapi.c | 3821 | ||||
-rw-r--r-- | mesalib/src/mesa/program/register_allocate.c | 883 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_extensions.c | 936 | ||||
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_split_copy.c | 1251 | ||||
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_split_inplace.c | 569 |
16 files changed, 18642 insertions, 18326 deletions
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h index e414ac8b5..0e2811ca6 100644 --- a/mesalib/src/glsl/ast.h +++ b/mesalib/src/glsl/ast.h @@ -1,725 +1,747 @@ -/* -*- c++ -*- */
-/*
- * Copyright © 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#pragma once
-#ifndef AST_H
-#define AST_H
-
-#include "list.h"
-#include "glsl_parser_extras.h"
-
-struct _mesa_glsl_parse_state;
-
-struct YYLTYPE;
-
-/**
- * \defgroup AST Abstract syntax tree node definitions
- *
- * An abstract syntax tree is generated by the parser. This is a fairly
- * direct representation of the gramma derivation for the source program.
- * No symantic checking is done during the generation of the AST. Only
- * syntactic checking is done. Symantic checking is performed by a later
- * stage that converts the AST to a more generic intermediate representation.
- *
- *@{
- */
-/**
- * Base class of all abstract syntax tree nodes
- */
-class ast_node {
-public:
- /* Callers of this talloc-based new need not call delete. It's
- * easier to just talloc_free 'ctx' (or any of its ancestors). */
- static void* operator new(size_t size, void *ctx)
- {
- void *node;
-
- node = talloc_zero_size(ctx, size);
- assert(node != NULL);
-
- return node;
- }
-
- /* If the user *does* call delete, that's OK, we will just
- * talloc_free in that case. */
- static void operator delete(void *table)
- {
- talloc_free(table);
- }
-
- /**
- * Print an AST node in something approximating the original GLSL code
- */
- virtual void print(void) const;
-
- /**
- * Convert the AST node to the high-level intermediate representation
- */
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- /**
- * Retrieve the source location of an AST node
- *
- * This function is primarily used to get the source position of an AST node
- * into a form that can be passed to \c _mesa_glsl_error.
- *
- * \sa _mesa_glsl_error, ast_node::set_location
- */
- struct YYLTYPE get_location(void) const
- {
- 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;
-
- return locp;
- }
-
- /**
- * Set the source location of an AST node from a parser location
- *
- * \sa ast_node::get_location
- */
- void set_location(const struct YYLTYPE &locp)
- {
- this->location.source = locp.source;
- this->location.line = locp.first_line;
- this->location.column = locp.first_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. */
- } location;
-
- exec_node link;
-
-protected:
- /**
- * The only constructor is protected so that only derived class objects can
- * be created.
- */
- ast_node(void);
-};
-
-
-/**
- * Operators for AST expression nodes.
- */
-enum ast_operators {
- ast_assign,
- ast_plus, /**< Unary + operator. */
- ast_neg,
- ast_add,
- ast_sub,
- ast_mul,
- ast_div,
- ast_mod,
- ast_lshift,
- ast_rshift,
- ast_less,
- ast_greater,
- ast_lequal,
- ast_gequal,
- ast_equal,
- ast_nequal,
- ast_bit_and,
- ast_bit_xor,
- ast_bit_or,
- ast_bit_not,
- ast_logic_and,
- ast_logic_xor,
- ast_logic_or,
- ast_logic_not,
-
- ast_mul_assign,
- ast_div_assign,
- ast_mod_assign,
- ast_add_assign,
- ast_sub_assign,
- ast_ls_assign,
- ast_rs_assign,
- ast_and_assign,
- ast_xor_assign,
- ast_or_assign,
-
- ast_conditional,
-
- ast_pre_inc,
- ast_pre_dec,
- ast_post_inc,
- ast_post_dec,
- ast_field_selection,
- ast_array_index,
-
- ast_function_call,
-
- ast_identifier,
- ast_int_constant,
- ast_uint_constant,
- ast_float_constant,
- ast_bool_constant,
-
- ast_sequence
-};
-
-/**
- * Representation of any sort of expression.
- */
-class ast_expression : public ast_node {
-public:
- ast_expression(int oper, ast_expression *,
- ast_expression *, ast_expression *);
-
- ast_expression(const char *identifier) :
- oper(ast_identifier)
- {
- subexpressions[0] = NULL;
- subexpressions[1] = NULL;
- subexpressions[2] = NULL;
- primary_expression.identifier = (char *) identifier;
- }
-
- static const char *operator_string(enum ast_operators op);
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- virtual void print(void) const;
-
- enum ast_operators oper;
-
- ast_expression *subexpressions[3];
-
- union {
- char *identifier;
- int int_constant;
- float float_constant;
- unsigned uint_constant;
- int bool_constant;
- } primary_expression;
-
-
- /**
- * List of expressions for an \c ast_sequence or parameters for an
- * \c ast_function_call
- */
- exec_list expressions;
-};
-
-class ast_expression_bin : public ast_expression {
-public:
- ast_expression_bin(int oper, ast_expression *, ast_expression *);
-
- virtual void print(void) const;
-};
-
-/**
- * Subclass of expressions for function calls
- */
-class ast_function_expression : public ast_expression {
-public:
- ast_function_expression(ast_expression *callee)
- : ast_expression(ast_function_call, callee,
- NULL, NULL),
- cons(false)
- {
- /* empty */
- }
-
- ast_function_expression(class ast_type_specifier *type)
- : ast_expression(ast_function_call, (ast_expression *) type,
- NULL, NULL),
- cons(true)
- {
- /* empty */
- }
-
- bool is_constructor() const
- {
- return cons;
- }
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
-private:
- /**
- * Is this function call actually a constructor?
- */
- bool cons;
-};
-
-
-/**
- * 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:
- ast_compound_statement(int new_scope, ast_node *statements);
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- int new_scope;
- exec_list statements;
-};
-
-class ast_declaration : public ast_node {
-public:
- ast_declaration(char *identifier, int is_array, ast_expression *array_size,
- ast_expression *initializer);
- virtual void print(void) const;
-
- char *identifier;
-
- int is_array;
- ast_expression *array_size;
-
- ast_expression *initializer;
-};
-
-
-enum {
- ast_precision_high = 0, /**< Default precision. */
- ast_precision_medium,
- ast_precision_low
-};
-
-struct ast_type_qualifier {
- union {
- struct {
- unsigned invariant:1;
- unsigned constant:1;
- unsigned attribute:1;
- unsigned varying:1;
- unsigned in:1;
- unsigned out:1;
- unsigned centroid:1;
- unsigned uniform:1;
- unsigned smooth:1;
- unsigned flat:1;
- unsigned noperspective:1;
-
- /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */
- /*@{*/
- unsigned origin_upper_left:1;
- unsigned pixel_center_integer:1;
- /*@}*/
-
- /**
- * Flag set if GL_ARB_explicit_attrib_location "location" layout
- * qualifier is used.
- */
- unsigned explicit_location:1;
- }
- /** \brief Set of flags, accessed by name. */
- q;
-
- /** \brief Set of flags, accessed as a bitmask. */
- unsigned i;
- } flags;
-
- /**
- * Location specified via GL_ARB_explicit_attrib_location layout
- *
- * \note
- * This field is only valid if \c explicit_location is set.
- */
- unsigned location;
-};
-
-class ast_struct_specifier : public ast_node {
-public:
- ast_struct_specifier(char *identifier, ast_node *declarator_list);
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- char *name;
- exec_list declarations;
-};
-
-
-enum ast_types {
- ast_void,
- ast_float,
- ast_int,
- ast_uint,
- ast_bool,
- ast_vec2,
- ast_vec3,
- ast_vec4,
- ast_bvec2,
- ast_bvec3,
- ast_bvec4,
- ast_ivec2,
- ast_ivec3,
- ast_ivec4,
- ast_uvec2,
- ast_uvec3,
- ast_uvec4,
- ast_mat2,
- ast_mat2x3,
- ast_mat2x4,
- ast_mat3x2,
- ast_mat3,
- ast_mat3x4,
- ast_mat4x2,
- ast_mat4x3,
- ast_mat4,
- ast_sampler1d,
- ast_sampler2d,
- ast_sampler2drect,
- ast_sampler3d,
- ast_samplercube,
- ast_sampler1dshadow,
- ast_sampler2dshadow,
- ast_sampler2drectshadow,
- ast_samplercubeshadow,
- ast_sampler1darray,
- ast_sampler2darray,
- ast_sampler1darrayshadow,
- ast_sampler2darrayshadow,
- ast_isampler1d,
- ast_isampler2d,
- ast_isampler3d,
- ast_isamplercube,
- ast_isampler1darray,
- ast_isampler2darray,
- ast_usampler1d,
- ast_usampler2d,
- ast_usampler3d,
- ast_usamplercube,
- ast_usampler1darray,
- ast_usampler2darray,
-
- ast_struct,
- ast_type_name
-};
-
-
-class ast_type_specifier : public ast_node {
-public:
- ast_type_specifier(int specifier);
-
- /** Construct a type specifier from a type name */
- ast_type_specifier(const char *name)
- : type_specifier(ast_type_name), type_name(name), structure(NULL),
- is_array(false), array_size(NULL), precision(ast_precision_high)
- {
- /* empty */
- }
-
- /** Construct a type specifier from a structure definition */
- ast_type_specifier(ast_struct_specifier *s)
- : type_specifier(ast_struct), type_name(s->name), structure(s),
- is_array(false), array_size(NULL), precision(ast_precision_high)
- {
- /* empty */
- }
-
- const struct glsl_type *glsl_type(const char **name,
- struct _mesa_glsl_parse_state *state)
- const;
-
- virtual void print(void) const;
-
- ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
-
- enum ast_types type_specifier;
-
- const char *type_name;
- ast_struct_specifier *structure;
-
- int is_array;
- ast_expression *array_size;
-
- unsigned precision:2;
-};
-
-
-class ast_fully_specified_type : public ast_node {
-public:
- virtual void print(void) const;
- bool has_qualifiers() const;
-
- ast_type_qualifier qualifier;
- ast_type_specifier *specifier;
-};
-
-
-class ast_declarator_list : public ast_node {
-public:
- ast_declarator_list(ast_fully_specified_type *);
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- ast_fully_specified_type *type;
- 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.
- */
- int invariant;
-};
-
-
-class ast_parameter_declarator : public ast_node {
-public:
- ast_parameter_declarator()
- {
- this->identifier = NULL;
- this->is_array = false;
- this->array_size = 0;
- }
-
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- ast_fully_specified_type *type;
- char *identifier;
- int is_array;
- ast_expression *array_size;
-
- static void parameters_to_hir(exec_list *ast_parameters,
- bool formal, exec_list *ir_parameters,
- struct _mesa_glsl_parse_state *state);
-
-private:
- /** Is this parameter declaration part of a formal parameter list? */
- bool formal_parameter;
-
- /**
- * Is this parameter 'void' type?
- *
- * This field is set by \c ::hir.
- */
- bool is_void;
-};
-
-
-class ast_function : public ast_node {
-public:
- ast_function(void);
-
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- ast_fully_specified_type *return_type;
- char *identifier;
-
- exec_list parameters;
-
-private:
- /**
- * Is this prototype part of the function definition?
- *
- * Used by ast_function_definition::hir to process the parameters, etc.
- * of the function.
- *
- * \sa ::hir
- */
- bool is_definition;
-
- /**
- * Function signature corresponding to this function prototype instance
- *
- * Used by ast_function_definition::hir to process the parameters, etc.
- * of the function.
- *
- * \sa ::hir
- */
- class ir_function_signature *signature;
-
- friend class ast_function_definition;
-};
-
-
-class ast_declaration_statement : public ast_node {
-public:
- ast_declaration_statement(void);
-
- enum {
- ast_function,
- ast_declaration,
- ast_precision
- } mode;
-
- union {
- class ast_function *function;
- ast_declarator_list *declarator;
- ast_type_specifier *type;
- ast_node *node;
- } declaration;
-};
-
-
-class ast_expression_statement : public ast_node {
-public:
- ast_expression_statement(ast_expression *);
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- ast_expression *expression;
-};
-
-
-class ast_case_label : public ast_node {
-public:
-
- /**
- * An expression of NULL means 'default'.
- */
- ast_expression *expression;
-};
-
-class ast_selection_statement : public ast_node {
-public:
- ast_selection_statement(ast_expression *condition,
- ast_node *then_statement,
- ast_node *else_statement);
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- ast_expression *condition;
- ast_node *then_statement;
- ast_node *else_statement;
-};
-
-
-class ast_switch_statement : public ast_node {
-public:
- ast_expression *expression;
- exec_list statements;
-};
-
-class ast_iteration_statement : public ast_node {
-public:
- ast_iteration_statement(int mode, ast_node *init, ast_node *condition,
- ast_expression *rest_expression, ast_node *body);
-
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
-
- enum ast_iteration_modes {
- ast_for,
- ast_while,
- ast_do_while
- } mode;
-
-
- ast_node *init_statement;
- ast_node *condition;
- ast_expression *rest_expression;
-
- 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 *);
-};
-
-
-class ast_jump_statement : public ast_node {
-public:
- ast_jump_statement(int mode, ast_expression *return_value);
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- enum ast_jump_modes {
- ast_continue,
- ast_break,
- ast_return,
- ast_discard
- } mode;
-
- ast_expression *opt_return_value;
-};
-
-
-class ast_function_definition : public ast_node {
-public:
- virtual void print(void) const;
-
- virtual ir_rvalue *hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
- ast_function *prototype;
- ast_compound_statement *body;
-};
-/*@}*/
-
-extern void
-_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state);
-
-extern ir_rvalue *
-_mesa_ast_field_selection_to_hir(const ast_expression *expr,
- exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
-void
-emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
- ir_function *f);
-
-#endif /* AST_H */
+/* -*- c++ -*- */ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once +#ifndef AST_H +#define AST_H + +#include "list.h" +#include "glsl_parser_extras.h" + +struct _mesa_glsl_parse_state; + +struct YYLTYPE; + +/** + * \defgroup AST Abstract syntax tree node definitions + * + * An abstract syntax tree is generated by the parser. This is a fairly + * direct representation of the gramma derivation for the source program. + * No symantic checking is done during the generation of the AST. Only + * syntactic checking is done. Symantic checking is performed by a later + * stage that converts the AST to a more generic intermediate representation. + * + *@{ + */ +/** + * Base class of all abstract syntax tree nodes + */ +class ast_node { +public: + /* Callers of this talloc-based new need not call delete. It's + * easier to just talloc_free 'ctx' (or any of its ancestors). */ + static void* operator new(size_t size, void *ctx) + { + void *node; + + node = talloc_zero_size(ctx, size); + assert(node != NULL); + + return node; + } + + /* If the user *does* call delete, that's OK, we will just + * talloc_free in that case. */ + static void operator delete(void *table) + { + talloc_free(table); + } + + /** + * Print an AST node in something approximating the original GLSL code + */ + virtual void print(void) const; + + /** + * Convert the AST node to the high-level intermediate representation + */ + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + /** + * Retrieve the source location of an AST node + * + * This function is primarily used to get the source position of an AST node + * into a form that can be passed to \c _mesa_glsl_error. + * + * \sa _mesa_glsl_error, ast_node::set_location + */ + struct YYLTYPE get_location(void) const + { + 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; + + return locp; + } + + /** + * Set the source location of an AST node from a parser location + * + * \sa ast_node::get_location + */ + void set_location(const struct YYLTYPE &locp) + { + this->location.source = locp.source; + this->location.line = locp.first_line; + this->location.column = locp.first_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. */ + } location; + + exec_node link; + +protected: + /** + * The only constructor is protected so that only derived class objects can + * be created. + */ + ast_node(void); +}; + + +/** + * Operators for AST expression nodes. + */ +enum ast_operators { + ast_assign, + ast_plus, /**< Unary + operator. */ + ast_neg, + ast_add, + ast_sub, + ast_mul, + ast_div, + ast_mod, + ast_lshift, + ast_rshift, + ast_less, + ast_greater, + ast_lequal, + ast_gequal, + ast_equal, + ast_nequal, + ast_bit_and, + ast_bit_xor, + ast_bit_or, + ast_bit_not, + ast_logic_and, + ast_logic_xor, + ast_logic_or, + ast_logic_not, + + ast_mul_assign, + ast_div_assign, + ast_mod_assign, + ast_add_assign, + ast_sub_assign, + ast_ls_assign, + ast_rs_assign, + ast_and_assign, + ast_xor_assign, + ast_or_assign, + + ast_conditional, + + ast_pre_inc, + ast_pre_dec, + ast_post_inc, + ast_post_dec, + ast_field_selection, + ast_array_index, + + ast_function_call, + + ast_identifier, + ast_int_constant, + ast_uint_constant, + ast_float_constant, + ast_bool_constant, + + ast_sequence +}; + +/** + * Representation of any sort of expression. + */ +class ast_expression : public ast_node { +public: + ast_expression(int oper, ast_expression *, + ast_expression *, ast_expression *); + + ast_expression(const char *identifier) : + oper(ast_identifier) + { + subexpressions[0] = NULL; + subexpressions[1] = NULL; + subexpressions[2] = NULL; + primary_expression.identifier = (char *) identifier; + } + + static const char *operator_string(enum ast_operators op); + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + virtual void print(void) const; + + enum ast_operators oper; + + ast_expression *subexpressions[3]; + + union { + char *identifier; + int int_constant; + float float_constant; + unsigned uint_constant; + int bool_constant; + } primary_expression; + + + /** + * List of expressions for an \c ast_sequence or parameters for an + * \c ast_function_call + */ + exec_list expressions; +}; + +class ast_expression_bin : public ast_expression { +public: + ast_expression_bin(int oper, ast_expression *, ast_expression *); + + virtual void print(void) const; +}; + +/** + * Subclass of expressions for function calls + */ +class ast_function_expression : public ast_expression { +public: + ast_function_expression(ast_expression *callee) + : ast_expression(ast_function_call, callee, + NULL, NULL), + cons(false) + { + /* empty */ + } + + ast_function_expression(class ast_type_specifier *type) + : ast_expression(ast_function_call, (ast_expression *) type, + NULL, NULL), + cons(true) + { + /* empty */ + } + + bool is_constructor() const + { + return cons; + } + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + +private: + /** + * Is this function call actually a constructor? + */ + bool cons; +}; + + +/** + * 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: + ast_compound_statement(int new_scope, ast_node *statements); + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + int new_scope; + exec_list statements; +}; + +class ast_declaration : public ast_node { +public: + ast_declaration(char *identifier, int is_array, ast_expression *array_size, + ast_expression *initializer); + virtual void print(void) const; + + char *identifier; + + int is_array; + ast_expression *array_size; + + ast_expression *initializer; +}; + + +enum { + ast_precision_none = 0, /**< Absence of precision qualifier. */ + ast_precision_high, + ast_precision_medium, + ast_precision_low +}; + +struct ast_type_qualifier { + union { + struct { + unsigned invariant:1; + unsigned constant:1; + unsigned attribute:1; + unsigned varying:1; + unsigned in:1; + unsigned out:1; + unsigned centroid:1; + unsigned uniform:1; + unsigned smooth:1; + unsigned flat:1; + unsigned noperspective:1; + + /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */ + /*@{*/ + unsigned origin_upper_left:1; + unsigned pixel_center_integer:1; + /*@}*/ + + /** + * Flag set if GL_ARB_explicit_attrib_location "location" layout + * qualifier is used. + */ + unsigned explicit_location:1; + } + /** \brief Set of flags, accessed by name. */ + q; + + /** \brief Set of flags, accessed as a bitmask. */ + unsigned i; + } flags; + + /** + * Location specified via GL_ARB_explicit_attrib_location layout + * + * \note + * This field is only valid if \c explicit_location is set. + */ + unsigned location; + + /** + * Return true if and only if an interpolation qualifier is present. + */ + bool has_interpolation() const; + + /** + * \brief Return string representation of interpolation qualifier. + * + * If an interpolation qualifier is present, then return that qualifier's + * string representation. Otherwise, return null. For example, if the + * noperspective bit is set, then this returns "noperspective". + * + * If multiple interpolation qualifiers are somehow present, then the + * returned string is undefined but not null. + */ + const char *interpolation_string() const; +}; + +class ast_struct_specifier : public ast_node { +public: + ast_struct_specifier(char *identifier, ast_node *declarator_list); + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + char *name; + exec_list declarations; +}; + + +enum ast_types { + ast_void, + ast_float, + ast_int, + ast_uint, + ast_bool, + ast_vec2, + ast_vec3, + ast_vec4, + ast_bvec2, + ast_bvec3, + ast_bvec4, + ast_ivec2, + ast_ivec3, + ast_ivec4, + ast_uvec2, + ast_uvec3, + ast_uvec4, + ast_mat2, + ast_mat2x3, + ast_mat2x4, + ast_mat3x2, + ast_mat3, + ast_mat3x4, + ast_mat4x2, + ast_mat4x3, + ast_mat4, + ast_sampler1d, + ast_sampler2d, + ast_sampler2drect, + ast_sampler3d, + ast_samplercube, + ast_sampler1dshadow, + ast_sampler2dshadow, + ast_sampler2drectshadow, + ast_samplercubeshadow, + ast_sampler1darray, + ast_sampler2darray, + ast_sampler1darrayshadow, + ast_sampler2darrayshadow, + ast_isampler1d, + ast_isampler2d, + ast_isampler3d, + ast_isamplercube, + ast_isampler1darray, + ast_isampler2darray, + ast_usampler1d, + ast_usampler2d, + ast_usampler3d, + ast_usamplercube, + ast_usampler1darray, + ast_usampler2darray, + + ast_struct, + ast_type_name +}; + + +class ast_type_specifier : public ast_node { +public: + ast_type_specifier(int specifier); + + /** Construct a type specifier from a type name */ + ast_type_specifier(const char *name) + : type_specifier(ast_type_name), type_name(name), structure(NULL), + is_array(false), array_size(NULL), precision(ast_precision_none), + is_precision_statement(false) + { + /* empty */ + } + + /** Construct a type specifier from a structure definition */ + ast_type_specifier(ast_struct_specifier *s) + : type_specifier(ast_struct), type_name(s->name), structure(s), + is_array(false), array_size(NULL), precision(ast_precision_none), + is_precision_statement(false) + { + /* empty */ + } + + const struct glsl_type *glsl_type(const char **name, + struct _mesa_glsl_parse_state *state) + const; + + virtual void print(void) const; + + ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *); + + enum ast_types type_specifier; + + const char *type_name; + ast_struct_specifier *structure; + + int is_array; + ast_expression *array_size; + + unsigned precision:2; + + bool is_precision_statement; +}; + + +class ast_fully_specified_type : public ast_node { +public: + virtual void print(void) const; + bool has_qualifiers() const; + + ast_type_qualifier qualifier; + ast_type_specifier *specifier; +}; + + +class ast_declarator_list : public ast_node { +public: + ast_declarator_list(ast_fully_specified_type *); + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + ast_fully_specified_type *type; + 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. + */ + int invariant; +}; + + +class ast_parameter_declarator : public ast_node { +public: + ast_parameter_declarator() + { + this->identifier = NULL; + this->is_array = false; + this->array_size = 0; + } + + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + ast_fully_specified_type *type; + char *identifier; + int is_array; + ast_expression *array_size; + + static void parameters_to_hir(exec_list *ast_parameters, + bool formal, exec_list *ir_parameters, + struct _mesa_glsl_parse_state *state); + +private: + /** Is this parameter declaration part of a formal parameter list? */ + bool formal_parameter; + + /** + * Is this parameter 'void' type? + * + * This field is set by \c ::hir. + */ + bool is_void; +}; + + +class ast_function : public ast_node { +public: + ast_function(void); + + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + ast_fully_specified_type *return_type; + char *identifier; + + exec_list parameters; + +private: + /** + * Is this prototype part of the function definition? + * + * Used by ast_function_definition::hir to process the parameters, etc. + * of the function. + * + * \sa ::hir + */ + bool is_definition; + + /** + * Function signature corresponding to this function prototype instance + * + * Used by ast_function_definition::hir to process the parameters, etc. + * of the function. + * + * \sa ::hir + */ + class ir_function_signature *signature; + + friend class ast_function_definition; +}; + + +class ast_declaration_statement : public ast_node { +public: + ast_declaration_statement(void); + + enum { + ast_function, + ast_declaration, + ast_precision + } mode; + + union { + class ast_function *function; + ast_declarator_list *declarator; + ast_type_specifier *type; + ast_node *node; + } declaration; +}; + + +class ast_expression_statement : public ast_node { +public: + ast_expression_statement(ast_expression *); + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + ast_expression *expression; +}; + + +class ast_case_label : public ast_node { +public: + + /** + * An expression of NULL means 'default'. + */ + ast_expression *expression; +}; + +class ast_selection_statement : public ast_node { +public: + ast_selection_statement(ast_expression *condition, + ast_node *then_statement, + ast_node *else_statement); + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + ast_expression *condition; + ast_node *then_statement; + ast_node *else_statement; +}; + + +class ast_switch_statement : public ast_node { +public: + ast_expression *expression; + exec_list statements; +}; + +class ast_iteration_statement : public ast_node { +public: + ast_iteration_statement(int mode, ast_node *init, ast_node *condition, + ast_expression *rest_expression, ast_node *body); + + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *); + + enum ast_iteration_modes { + ast_for, + ast_while, + ast_do_while + } mode; + + + ast_node *init_statement; + ast_node *condition; + ast_expression *rest_expression; + + 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 *); +}; + + +class ast_jump_statement : public ast_node { +public: + ast_jump_statement(int mode, ast_expression *return_value); + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + enum ast_jump_modes { + ast_continue, + ast_break, + ast_return, + ast_discard + } mode; + + ast_expression *opt_return_value; +}; + + +class ast_function_definition : public ast_node { +public: + virtual void print(void) const; + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + ast_function *prototype; + ast_compound_statement *body; +}; +/*@}*/ + +extern void +_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); + +extern ir_rvalue * +_mesa_ast_field_selection_to_hir(const ast_expression *expr, + exec_list *instructions, + struct _mesa_glsl_parse_state *state); + +void +emit_function(_mesa_glsl_parse_state *state, exec_list *instructions, + ir_function *f); + +#endif /* AST_H */ diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 365a6e267..7a171f3a2 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2277,6 +2277,112 @@ ast_declarator_list::hir(exec_list *instructions, } + /* Interpolation qualifiers cannot be applied to 'centroid' and + * 'centroid varying'. + * + * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec: + * "interpolation qualifiers may only precede the qualifiers in, + * centroid in, out, or centroid out in a declaration. They do not apply + * to the deprecated storage qualifiers varying or centroid varying." + */ + if (state->language_version >= 130 + && this->type->qualifier.has_interpolation() + && this->type->qualifier.flags.q.varying) { + + const char *i = this->type->qualifier.interpolation_string(); + assert(i != NULL); + const char *s; + if (this->type->qualifier.flags.q.centroid) + s = "centroid varying"; + else + s = "varying"; + + _mesa_glsl_error(&loc, state, + "qualifier '%s' cannot be applied to the " + "deprecated storage qualifier '%s'", i, s); + } + + + /* Interpolation qualifiers can only apply to vertex shader outputs and + * fragment shader inputs. + * + * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec: + * "Outputs from a vertex shader (out) and inputs to a fragment + * shader (in) can be further qualified with one or more of these + * interpolation qualifiers" + */ + if (state->language_version >= 130 + && this->type->qualifier.has_interpolation()) { + + const char *i = this->type->qualifier.interpolation_string(); + assert(i != NULL); + + switch (state->target) { + case vertex_shader: + if (this->type->qualifier.flags.q.in) { + _mesa_glsl_error(&loc, state, + "qualifier '%s' cannot be applied to vertex " + "shader inputs", i); + } + break; + case fragment_shader: + if (this->type->qualifier.flags.q.out) { + _mesa_glsl_error(&loc, state, + "qualifier '%s' cannot be applied to fragment " + "shader outputs", i); + } + break; + default: + assert(0); + } + } + + + /* From section 4.3.4 of the GLSL 1.30 spec: + * "It is an error to use centroid in in a vertex shader." + */ + if (state->language_version >= 130 + && this->type->qualifier.flags.q.centroid + && this->type->qualifier.flags.q.in + && state->target == vertex_shader) { + + _mesa_glsl_error(&loc, state, + "'centroid in' cannot be used in a vertex shader"); + } + + + /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30. + */ + if (this->type->specifier->precision != ast_precision_none + && state->language_version != 100 + && state->language_version < 130) { + + _mesa_glsl_error(&loc, state, + "precision qualifiers are supported only in GLSL ES " + "1.00, and GLSL 1.30 and later"); + } + + + /* Precision qualifiers only apply to floating point and integer types. + * + * From section 4.5.2 of the GLSL 1.30 spec: + * "Any floating point or any integer declaration can have the type + * preceded by one of these precision qualifiers [...] Literal + * constants do not have precision qualifiers. Neither do Boolean + * variables. + */ + if (this->type->specifier->precision != ast_precision_none + && !var->type->is_float() + && !var->type->is_integer() + && !(var->type->is_array() + && (var->type->fields.array->is_float() + || var->type->fields.array->is_integer()))) { + + _mesa_glsl_error(&loc, state, + "precision qualifiers apply only to floating point " + "and integer types"); + } + /* 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 @@ -2403,7 +2509,8 @@ ast_declarator_list::hir(exec_list *instructions, */ if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) { _mesa_glsl_error(& loc, state, - "const declaration of `%s' must be initialized"); + "const declaration of `%s' must be initialized", + decl->identifier); } /* Check if this declaration is actually a re-declaration, either to @@ -3132,6 +3239,58 @@ ir_rvalue * ast_type_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + if (!this->is_precision_statement && this->structure == NULL) + return NULL; + + YYLTYPE loc = this->get_location(); + + if (this->precision != ast_precision_none + && state->language_version != 100 + && state->language_version < 130) { + _mesa_glsl_error(&loc, state, + "precision qualifiers exist only in " + "GLSL ES 1.00, and GLSL 1.30 and later"); + return NULL; + } + if (this->precision != ast_precision_none + && this->structure != NULL) { + _mesa_glsl_error(&loc, state, + "precision qualifiers do not apply to structures"); + return NULL; + } + + /* If this is a precision statement, check that the type to which it is + * applied is either float or int. + * + * From section 4.5.3 of the GLSL 1.30 spec: + * "The precision statement + * precision precision-qualifier type; + * can be used to establish a default precision qualifier. The type + * field can be either int or float [...]. Any other types or + * qualifiers will result in an error. + */ + if (this->is_precision_statement) { + assert(this->precision != ast_precision_none); + assert(this->structure == NULL); /* The check for structures was + * performed above. */ + if (this->is_array) { + _mesa_glsl_error(&loc, state, + "default precision statements do not apply to " + "arrays"); + return NULL; + } + if (this->type_specifier != ast_float + && this->type_specifier != ast_int) { + _mesa_glsl_error(&loc, state, + "default precision statements apply only to types " + "float and int"); + return NULL; + } + + /* FINISHME: Translate precision statements into IR. */ + return NULL; + } + if (this->structure != NULL) return this->structure->hir(instructions, state); diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp index c1cf43591..d14077473 100644 --- a/mesalib/src/glsl/ast_type.cpp +++ b/mesalib/src/glsl/ast_type.cpp @@ -1,118 +1,139 @@ -/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <cstdio>
-#include "ast.h"
-extern "C" {
-#include "program/symbol_table.h"
-}
-
-void
-ast_type_specifier::print(void) const
-{
- if (type_specifier == ast_struct) {
- structure->print();
- } else {
- printf("%s ", type_name);
- }
-
- if (is_array) {
- printf("[ ");
-
- if (array_size) {
- array_size->print();
- }
-
- printf("] ");
- }
-}
-
-ast_type_specifier::ast_type_specifier(int specifier)
- : type_specifier(ast_types(specifier)), type_name(NULL), structure(NULL),
- is_array(false), array_size(NULL), precision(ast_precision_high)
-{
- static const char *const names[] = {
- "void",
- "float",
- "int",
- "uint",
- "bool",
- "vec2",
- "vec3",
- "vec4",
- "bvec2",
- "bvec3",
- "bvec4",
- "ivec2",
- "ivec3",
- "ivec4",
- "uvec2",
- "uvec3",
- "uvec4",
- "mat2",
- "mat2x3",
- "mat2x4",
- "mat3x2",
- "mat3",
- "mat3x4",
- "mat4x2",
- "mat4x3",
- "mat4",
- "sampler1D",
- "sampler2D",
- "sampler2DRect",
- "sampler3D",
- "samplerCube",
- "sampler1DShadow",
- "sampler2DShadow",
- "sampler2DRectShadow",
- "samplerCubeShadow",
- "sampler1DArray",
- "sampler2DArray",
- "sampler1DArrayShadow",
- "sampler2DArrayShadow",
- "isampler1D",
- "isampler2D",
- "isampler3D",
- "isamplerCube",
- "isampler1DArray",
- "isampler2DArray",
- "usampler1D",
- "usampler2D",
- "usampler3D",
- "usamplerCube",
- "usampler1DArray",
- "usampler2DArray",
-
- NULL, /* ast_struct */
- NULL /* ast_type_name */
- };
-
- type_name = names[specifier];
-}
-
-bool
-ast_fully_specified_type::has_qualifiers() const
-{
- return this->qualifier.flags.i != 0;
-}
+/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <cstdio> +#include "ast.h" +extern "C" { +#include "program/symbol_table.h" +} + +void +ast_type_specifier::print(void) const +{ + if (type_specifier == ast_struct) { + structure->print(); + } else { + printf("%s ", type_name); + } + + if (is_array) { + printf("[ "); + + if (array_size) { + array_size->print(); + } + + printf("] "); + } +} + +ast_type_specifier::ast_type_specifier(int specifier) + : type_specifier(ast_types(specifier)), type_name(NULL), structure(NULL), + is_array(false), array_size(NULL), precision(ast_precision_none), + is_precision_statement(false) +{ + static const char *const names[] = { + "void", + "float", + "int", + "uint", + "bool", + "vec2", + "vec3", + "vec4", + "bvec2", + "bvec3", + "bvec4", + "ivec2", + "ivec3", + "ivec4", + "uvec2", + "uvec3", + "uvec4", + "mat2", + "mat2x3", + "mat2x4", + "mat3x2", + "mat3", + "mat3x4", + "mat4x2", + "mat4x3", + "mat4", + "sampler1D", + "sampler2D", + "sampler2DRect", + "sampler3D", + "samplerCube", + "sampler1DShadow", + "sampler2DShadow", + "sampler2DRectShadow", + "samplerCubeShadow", + "sampler1DArray", + "sampler2DArray", + "sampler1DArrayShadow", + "sampler2DArrayShadow", + "isampler1D", + "isampler2D", + "isampler3D", + "isamplerCube", + "isampler1DArray", + "isampler2DArray", + "usampler1D", + "usampler2D", + "usampler3D", + "usamplerCube", + "usampler1DArray", + "usampler2DArray", + + NULL, /* ast_struct */ + NULL /* ast_type_name */ + }; + + type_name = names[specifier]; +} + +bool +ast_fully_specified_type::has_qualifiers() const +{ + return this->qualifier.flags.i != 0; +} + +bool ast_type_qualifier::has_interpolation() const +{ + return this->flags.q.smooth + || this->flags.q.flat + || this->flags.q.noperspective; +} + +const char* +ast_type_qualifier::interpolation_string() const +{ + if (this->flags.q.smooth) + return "smooth"; + else if (this->flags.q.flat) + return "flat"; + else if (this->flags.q.noperspective) + return "noperspective"; + else + return NULL; +} diff --git a/mesalib/src/glsl/glsl_parser.cpp b/mesalib/src/glsl/glsl_parser.cpp index bdf08d869..8b196ae7f 100644 --- a/mesalib/src/glsl/glsl_parser.cpp +++ b/mesalib/src/glsl/glsl_parser.cpp @@ -1,5320 +1,5332 @@ -
-/* A Bison parser, made by GNU Bison 2.4.1. */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
- simplifying the original so-called "semantic" parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Bison version. */
-#define YYBISON_VERSION "2.4.1"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 1
-
-/* Push parsers. */
-#define YYPUSH 0
-
-/* Pull parsers. */
-#define YYPULL 1
-
-/* Using locations. */
-#define YYLSP_NEEDED 1
-
-/* Substitute the variable and function names. */
-#define yyparse _mesa_glsl_parse
-#define yylex _mesa_glsl_lex
-#define yyerror _mesa_glsl_error
-#define yylval _mesa_glsl_lval
-#define yychar _mesa_glsl_char
-#define yydebug _mesa_glsl_debug
-#define yynerrs _mesa_glsl_nerrs
-#define yylloc _mesa_glsl_lloc
-
-/* Copy the first part of user declarations. */
-
-/* Line 189 of yacc.c */
-#line 1 "glsl_parser.ypp"
-
-/*
- * Copyright © 2008, 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "ast.h"
-#include "glsl_parser_extras.h"
-#include "glsl_types.h"
-
-#define YYLEX_PARAM state->scanner
-
-
-
-/* Line 189 of yacc.c */
-#line 118 "glsl_parser.cpp"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 1
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- ATTRIBUTE = 258,
- CONST_TOK = 259,
- BOOL_TOK = 260,
- FLOAT_TOK = 261,
- INT_TOK = 262,
- UINT_TOK = 263,
- BREAK = 264,
- CONTINUE = 265,
- DO = 266,
- ELSE = 267,
- FOR = 268,
- IF = 269,
- DISCARD = 270,
- RETURN = 271,
- SWITCH = 272,
- CASE = 273,
- DEFAULT = 274,
- BVEC2 = 275,
- BVEC3 = 276,
- BVEC4 = 277,
- IVEC2 = 278,
- IVEC3 = 279,
- IVEC4 = 280,
- UVEC2 = 281,
- UVEC3 = 282,
- UVEC4 = 283,
- VEC2 = 284,
- VEC3 = 285,
- VEC4 = 286,
- CENTROID = 287,
- IN_TOK = 288,
- OUT_TOK = 289,
- INOUT_TOK = 290,
- UNIFORM = 291,
- VARYING = 292,
- NOPERSPECTIVE = 293,
- FLAT = 294,
- SMOOTH = 295,
- MAT2X2 = 296,
- MAT2X3 = 297,
- MAT2X4 = 298,
- MAT3X2 = 299,
- MAT3X3 = 300,
- MAT3X4 = 301,
- MAT4X2 = 302,
- MAT4X3 = 303,
- MAT4X4 = 304,
- SAMPLER1D = 305,
- SAMPLER2D = 306,
- SAMPLER3D = 307,
- SAMPLERCUBE = 308,
- SAMPLER1DSHADOW = 309,
- SAMPLER2DSHADOW = 310,
- SAMPLERCUBESHADOW = 311,
- SAMPLER1DARRAY = 312,
- SAMPLER2DARRAY = 313,
- SAMPLER1DARRAYSHADOW = 314,
- SAMPLER2DARRAYSHADOW = 315,
- ISAMPLER1D = 316,
- ISAMPLER2D = 317,
- ISAMPLER3D = 318,
- ISAMPLERCUBE = 319,
- ISAMPLER1DARRAY = 320,
- ISAMPLER2DARRAY = 321,
- USAMPLER1D = 322,
- USAMPLER2D = 323,
- USAMPLER3D = 324,
- USAMPLERCUBE = 325,
- USAMPLER1DARRAY = 326,
- USAMPLER2DARRAY = 327,
- STRUCT = 328,
- VOID_TOK = 329,
- WHILE = 330,
- IDENTIFIER = 331,
- FLOATCONSTANT = 332,
- INTCONSTANT = 333,
- UINTCONSTANT = 334,
- BOOLCONSTANT = 335,
- FIELD_SELECTION = 336,
- LEFT_OP = 337,
- RIGHT_OP = 338,
- INC_OP = 339,
- DEC_OP = 340,
- LE_OP = 341,
- GE_OP = 342,
- EQ_OP = 343,
- NE_OP = 344,
- AND_OP = 345,
- OR_OP = 346,
- XOR_OP = 347,
- MUL_ASSIGN = 348,
- DIV_ASSIGN = 349,
- ADD_ASSIGN = 350,
- MOD_ASSIGN = 351,
- LEFT_ASSIGN = 352,
- RIGHT_ASSIGN = 353,
- AND_ASSIGN = 354,
- XOR_ASSIGN = 355,
- OR_ASSIGN = 356,
- SUB_ASSIGN = 357,
- INVARIANT = 358,
- LOWP = 359,
- MEDIUMP = 360,
- HIGHP = 361,
- SUPERP = 362,
- PRECISION = 363,
- VERSION = 364,
- EXTENSION = 365,
- LINE = 366,
- COLON = 367,
- EOL = 368,
- INTERFACE = 369,
- OUTPUT = 370,
- PRAGMA_DEBUG_ON = 371,
- PRAGMA_DEBUG_OFF = 372,
- PRAGMA_OPTIMIZE_ON = 373,
- PRAGMA_OPTIMIZE_OFF = 374,
- PRAGMA_INVARIANT_ALL = 375,
- LAYOUT_TOK = 376,
- ASM = 377,
- CLASS = 378,
- UNION = 379,
- ENUM = 380,
- TYPEDEF = 381,
- TEMPLATE = 382,
- THIS = 383,
- PACKED_TOK = 384,
- GOTO = 385,
- INLINE_TOK = 386,
- NOINLINE = 387,
- VOLATILE = 388,
- PUBLIC_TOK = 389,
- STATIC = 390,
- EXTERN = 391,
- EXTERNAL = 392,
- LONG_TOK = 393,
- SHORT_TOK = 394,
- DOUBLE_TOK = 395,
- HALF = 396,
- FIXED_TOK = 397,
- UNSIGNED = 398,
- INPUT_TOK = 399,
- OUPTUT = 400,
- HVEC2 = 401,
- HVEC3 = 402,
- HVEC4 = 403,
- DVEC2 = 404,
- DVEC3 = 405,
- DVEC4 = 406,
- FVEC2 = 407,
- FVEC3 = 408,
- FVEC4 = 409,
- SAMPLER2DRECT = 410,
- SAMPLER3DRECT = 411,
- SAMPLER2DRECTSHADOW = 412,
- SIZEOF = 413,
- CAST = 414,
- NAMESPACE = 415,
- USING = 416,
- ERROR_TOK = 417,
- COMMON = 418,
- PARTITION = 419,
- ACTIVE = 420,
- SAMPLERBUFFER = 421,
- FILTER = 422,
- IMAGE1D = 423,
- IMAGE2D = 424,
- IMAGE3D = 425,
- IMAGECUBE = 426,
- IMAGE1DARRAY = 427,
- IMAGE2DARRAY = 428,
- IIMAGE1D = 429,
- IIMAGE2D = 430,
- IIMAGE3D = 431,
- IIMAGECUBE = 432,
- IIMAGE1DARRAY = 433,
- IIMAGE2DARRAY = 434,
- UIMAGE1D = 435,
- UIMAGE2D = 436,
- UIMAGE3D = 437,
- UIMAGECUBE = 438,
- UIMAGE1DARRAY = 439,
- UIMAGE2DARRAY = 440,
- IMAGE1DSHADOW = 441,
- IMAGE2DSHADOW = 442,
- IMAGEBUFFER = 443,
- IIMAGEBUFFER = 444,
- UIMAGEBUFFER = 445,
- IMAGE1DARRAYSHADOW = 446,
- IMAGE2DARRAYSHADOW = 447,
- ROW_MAJOR = 448
- };
-#endif
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 214 of yacc.c */
-#line 52 "glsl_parser.ypp"
-
- int n;
- float real;
- char *identifier;
-
- struct ast_type_qualifier type_qualifier;
-
- ast_node *node;
- ast_type_specifier *type_specifier;
- ast_fully_specified_type *fully_specified_type;
- ast_function *function;
- ast_parameter_declarator *parameter_declarator;
- ast_function_definition *function_definition;
- ast_compound_statement *compound_statement;
- ast_expression *expression;
- ast_declarator_list *declarator_list;
- ast_struct_specifier *struct_specifier;
- ast_declaration *declaration;
-
- struct {
- ast_node *cond;
- ast_expression *rest;
- } for_rest_statement;
-
- struct {
- ast_node *then_statement;
- ast_node *else_statement;
- } selection_rest_statement;
-
-
-
-/* Line 214 of yacc.c */
-#line 379 "glsl_parser.cpp"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-/* Copy the second part of user declarations. */
-
-
-/* Line 264 of yacc.c */
-#line 404 "glsl_parser.cpp"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-# define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# else
-# define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if YYENABLE_NLS
-# if ENABLE_NLS
-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
-# endif
-# endif
-# ifndef YY_
-# define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E. */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
-#else
-static int
-YYID (yyi)
- int yyi;
-#endif
-{
- return yyi;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# elif defined __BUILTIN_VA_ARG_INCR
-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-# ifndef YYSTACK_ALLOC_MAXIMUM
- /* The OS might guarantee only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
- to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-# endif
-# else
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-# endif
-# if (defined __cplusplus && ! defined _STDLIB_H \
- && ! ((defined YYMALLOC || defined malloc) \
- && (defined YYFREE || defined free)))
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifndef YYFREE
-# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
- && (! defined __cplusplus \
- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- yytype_int16 yyss_alloc;
- YYSTYPE yyvs_alloc;
- YYLTYPE yyls_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
- + 2 * YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 5
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 3738
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 218
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 87
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 279
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 415
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 448
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const yytype_uint8 yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 202, 2, 2, 2, 206, 209, 2,
- 194, 195, 204, 200, 199, 201, 198, 205, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 213, 215,
- 207, 214, 208, 212, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 196, 2, 197, 210, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 216, 211, 217, 203, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
- 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
- 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
- 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
- 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
- 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
- 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
- 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
- 185, 186, 187, 188, 189, 190, 191, 192, 193
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint16 yyprhs[] =
-{
- 0, 0, 3, 4, 9, 10, 14, 17, 20, 23,
- 26, 29, 30, 33, 39, 41, 44, 46, 48, 50,
- 52, 54, 56, 60, 62, 67, 69, 73, 76, 79,
- 81, 83, 85, 89, 92, 95, 98, 100, 103, 107,
- 110, 112, 114, 116, 118, 121, 124, 127, 129, 131,
- 133, 135, 137, 141, 145, 149, 151, 155, 159, 161,
- 165, 169, 171, 175, 179, 183, 187, 189, 193, 197,
- 199, 203, 205, 209, 211, 215, 217, 221, 223, 227,
- 229, 233, 235, 241, 243, 247, 249, 251, 253, 255,
- 257, 259, 261, 263, 265, 267, 269, 271, 275, 277,
- 280, 283, 288, 291, 293, 295, 298, 302, 306, 309,
- 315, 319, 322, 326, 329, 330, 332, 334, 336, 338,
- 340, 344, 350, 357, 365, 374, 380, 382, 385, 390,
- 396, 403, 411, 416, 419, 421, 424, 429, 431, 435,
- 437, 441, 443, 445, 447, 449, 451, 453, 456, 458,
- 461, 464, 468, 470, 472, 474, 476, 479, 481, 483,
- 486, 489, 491, 493, 496, 498, 502, 507, 509, 511,
- 513, 515, 517, 519, 521, 523, 525, 527, 529, 531,
- 533, 535, 537, 539, 541, 543, 545, 547, 549, 551,
- 553, 555, 557, 559, 561, 563, 565, 567, 569, 571,
- 573, 575, 577, 579, 581, 583, 585, 587, 589, 591,
- 593, 595, 597, 599, 601, 603, 605, 607, 609, 611,
- 613, 615, 617, 619, 621, 627, 632, 634, 637, 641,
- 643, 647, 649, 654, 656, 658, 660, 662, 664, 666,
- 668, 670, 672, 674, 676, 679, 683, 685, 687, 690,
- 694, 696, 699, 701, 704, 710, 714, 716, 718, 723,
- 729, 733, 736, 742, 750, 757, 759, 761, 763, 764,
- 767, 771, 774, 777, 780, 784, 787, 789, 791, 793
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int16 yyrhs[] =
-{
- 219, 0, -1, -1, 221, 223, 220, 225, -1, -1,
- 109, 78, 113, -1, 116, 113, -1, 117, 113, -1,
- 118, 113, -1, 119, 113, -1, 120, 113, -1, -1,
- 223, 224, -1, 110, 76, 112, 76, 113, -1, 303,
- -1, 225, 303, -1, 76, -1, 226, -1, 78, -1,
- 79, -1, 77, -1, 80, -1, 194, 253, 195, -1,
- 227, -1, 228, 196, 229, 197, -1, 230, -1, 228,
- 198, 76, -1, 228, 84, -1, 228, 85, -1, 253,
- -1, 231, -1, 232, -1, 228, 198, 232, -1, 234,
- 195, -1, 233, 195, -1, 235, 74, -1, 235, -1,
- 235, 251, -1, 234, 199, 251, -1, 236, 194, -1,
- 274, -1, 76, -1, 81, -1, 228, -1, 84, 237,
- -1, 85, 237, -1, 238, 237, -1, 200, -1, 201,
- -1, 202, -1, 203, -1, 237, -1, 239, 204, 237,
- -1, 239, 205, 237, -1, 239, 206, 237, -1, 239,
- -1, 240, 200, 239, -1, 240, 201, 239, -1, 240,
- -1, 241, 82, 240, -1, 241, 83, 240, -1, 241,
- -1, 242, 207, 241, -1, 242, 208, 241, -1, 242,
- 86, 241, -1, 242, 87, 241, -1, 242, -1, 243,
- 88, 242, -1, 243, 89, 242, -1, 243, -1, 244,
- 209, 243, -1, 244, -1, 245, 210, 244, -1, 245,
- -1, 246, 211, 245, -1, 246, -1, 247, 90, 246,
- -1, 247, -1, 248, 92, 247, -1, 248, -1, 249,
- 91, 248, -1, 249, -1, 249, 212, 253, 213, 251,
- -1, 250, -1, 237, 252, 251, -1, 214, -1, 93,
- -1, 94, -1, 96, -1, 95, -1, 102, -1, 97,
- -1, 98, -1, 99, -1, 100, -1, 101, -1, 251,
- -1, 253, 199, 251, -1, 250, -1, 256, 215, -1,
- 264, 215, -1, 108, 278, 275, 215, -1, 257, 195,
- -1, 259, -1, 258, -1, 259, 261, -1, 258, 199,
- 261, -1, 266, 76, 194, -1, 274, 76, -1, 274,
- 76, 196, 254, 197, -1, 271, 262, 260, -1, 262,
- 260, -1, 271, 262, 263, -1, 262, 263, -1, -1,
- 33, -1, 34, -1, 35, -1, 274, -1, 265, -1,
- 264, 199, 76, -1, 264, 199, 76, 196, 197, -1,
- 264, 199, 76, 196, 254, 197, -1, 264, 199, 76,
- 196, 197, 214, 284, -1, 264, 199, 76, 196, 254,
- 197, 214, 284, -1, 264, 199, 76, 214, 284, -1,
- 266, -1, 266, 76, -1, 266, 76, 196, 197, -1,
- 266, 76, 196, 254, 197, -1, 266, 76, 196, 197,
- 214, 284, -1, 266, 76, 196, 254, 197, 214, 284,
- -1, 266, 76, 214, 284, -1, 103, 76, -1, 274,
- -1, 272, 274, -1, 121, 194, 268, 195, -1, 269,
- -1, 268, 199, 269, -1, 76, -1, 76, 214, 78,
- -1, 40, -1, 39, -1, 38, -1, 4, -1, 273,
- -1, 267, -1, 267, 273, -1, 270, -1, 270, 273,
- -1, 103, 273, -1, 103, 270, 273, -1, 103, -1,
- 4, -1, 3, -1, 37, -1, 32, 37, -1, 33,
- -1, 34, -1, 32, 33, -1, 32, 34, -1, 36,
- -1, 275, -1, 278, 275, -1, 276, -1, 276, 196,
- 197, -1, 276, 196, 254, 197, -1, 277, -1, 279,
- -1, 76, -1, 74, -1, 6, -1, 7, -1, 8,
- -1, 5, -1, 29, -1, 30, -1, 31, -1, 20,
- -1, 21, -1, 22, -1, 23, -1, 24, -1, 25,
- -1, 26, -1, 27, -1, 28, -1, 41, -1, 42,
- -1, 43, -1, 44, -1, 45, -1, 46, -1, 47,
- -1, 48, -1, 49, -1, 50, -1, 51, -1, 155,
- -1, 52, -1, 53, -1, 54, -1, 55, -1, 157,
- -1, 56, -1, 57, -1, 58, -1, 59, -1, 60,
- -1, 61, -1, 62, -1, 63, -1, 64, -1, 65,
- -1, 66, -1, 67, -1, 68, -1, 69, -1, 70,
- -1, 71, -1, 72, -1, 106, -1, 105, -1, 104,
- -1, 73, 76, 216, 280, 217, -1, 73, 216, 280,
- 217, -1, 281, -1, 280, 281, -1, 274, 282, 215,
- -1, 283, -1, 282, 199, 283, -1, 76, -1, 76,
- 196, 254, 197, -1, 251, -1, 255, -1, 288, -1,
- 287, -1, 285, -1, 292, -1, 293, -1, 296, -1,
- 297, -1, 298, -1, 302, -1, 216, 217, -1, 216,
- 291, 217, -1, 290, -1, 287, -1, 216, 217, -1,
- 216, 291, 217, -1, 286, -1, 291, 286, -1, 215,
- -1, 253, 215, -1, 14, 194, 253, 195, 294, -1,
- 286, 12, 286, -1, 286, -1, 253, -1, 266, 76,
- 214, 284, -1, 17, 194, 253, 195, 288, -1, 18,
- 253, 213, -1, 19, 213, -1, 75, 194, 295, 195,
- 289, -1, 11, 286, 75, 194, 253, 195, 215, -1,
- 13, 194, 299, 301, 195, 289, -1, 292, -1, 285,
- -1, 295, -1, -1, 300, 215, -1, 300, 215, 253,
- -1, 10, 215, -1, 9, 215, -1, 16, 215, -1,
- 16, 253, 215, -1, 15, 215, -1, 304, -1, 255,
- -1, 222, -1, 256, 290, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint16 yyrline[] =
-{
- 0, 213, 213, 212, 219, 221, 246, 247, 248, 249,
- 250, 262, 264, 268, 277, 285, 296, 300, 307, 314,
- 321, 328, 335, 342, 343, 349, 353, 360, 366, 375,
- 379, 383, 384, 393, 394, 398, 399, 403, 409, 421,
- 425, 431, 438, 449, 450, 456, 462, 472, 473, 474,
- 475, 479, 480, 486, 492, 501, 502, 508, 517, 518,
- 524, 533, 534, 540, 546, 552, 561, 562, 568, 577,
- 578, 587, 588, 597, 598, 607, 608, 617, 618, 627,
- 628, 637, 638, 647, 648, 657, 658, 659, 660, 661,
- 662, 663, 664, 665, 666, 667, 671, 675, 691, 695,
- 699, 703, 717, 721, 722, 726, 731, 739, 750, 760,
- 775, 782, 787, 798, 811, 814, 819, 824, 833, 837,
- 838, 847, 856, 865, 874, 883, 896, 907, 916, 925,
- 934, 943, 952, 961, 975, 982, 993, 1000, 1001, 1020,
- 1049, 1090, 1095, 1100, 1108, 1116, 1117, 1118, 1123, 1124,
- 1129, 1134, 1140, 1148, 1153, 1158, 1163, 1169, 1174, 1179,
- 1184, 1189, 1197, 1198, 1206, 1207, 1213, 1222, 1228, 1234,
- 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252,
- 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262,
- 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272,
- 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282,
- 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292,
- 1293, 1297, 1307, 1317, 1330, 1336, 1345, 1350, 1358, 1373,
- 1378, 1386, 1392, 1401, 1405, 1411, 1412, 1416, 1417, 1418,
- 1419, 1420, 1421, 1422, 1426, 1432, 1441, 1442, 1446, 1452,
- 1461, 1471, 1483, 1489, 1498, 1507, 1512, 1520, 1524, 1538,
- 1542, 1543, 1547, 1554, 1561, 1571, 1572, 1576, 1578, 1584,
- 1589, 1598, 1604, 1610, 1616, 1622, 1631, 1632, 1633, 1637
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "ATTRIBUTE", "CONST_TOK", "BOOL_TOK",
- "FLOAT_TOK", "INT_TOK", "UINT_TOK", "BREAK", "CONTINUE", "DO", "ELSE",
- "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "BVEC2",
- "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "UVEC2", "UVEC3", "UVEC4",
- "VEC2", "VEC3", "VEC4", "CENTROID", "IN_TOK", "OUT_TOK", "INOUT_TOK",
- "UNIFORM", "VARYING", "NOPERSPECTIVE", "FLAT", "SMOOTH", "MAT2X2",
- "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3",
- "MAT4X4", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE",
- "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW",
- "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW",
- "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D",
- "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D",
- "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY",
- "USAMPLER2DARRAY", "STRUCT", "VOID_TOK", "WHILE", "IDENTIFIER",
- "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT",
- "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP",
- "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN",
- "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN",
- "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "INVARIANT",
- "LOWP", "MEDIUMP", "HIGHP", "SUPERP", "PRECISION", "VERSION",
- "EXTENSION", "LINE", "COLON", "EOL", "INTERFACE", "OUTPUT",
- "PRAGMA_DEBUG_ON", "PRAGMA_DEBUG_OFF", "PRAGMA_OPTIMIZE_ON",
- "PRAGMA_OPTIMIZE_OFF", "PRAGMA_INVARIANT_ALL", "LAYOUT_TOK", "ASM",
- "CLASS", "UNION", "ENUM", "TYPEDEF", "TEMPLATE", "THIS", "PACKED_TOK",
- "GOTO", "INLINE_TOK", "NOINLINE", "VOLATILE", "PUBLIC_TOK", "STATIC",
- "EXTERN", "EXTERNAL", "LONG_TOK", "SHORT_TOK", "DOUBLE_TOK", "HALF",
- "FIXED_TOK", "UNSIGNED", "INPUT_TOK", "OUPTUT", "HVEC2", "HVEC3",
- "HVEC4", "DVEC2", "DVEC3", "DVEC4", "FVEC2", "FVEC3", "FVEC4",
- "SAMPLER2DRECT", "SAMPLER3DRECT", "SAMPLER2DRECTSHADOW", "SIZEOF",
- "CAST", "NAMESPACE", "USING", "ERROR_TOK", "COMMON", "PARTITION",
- "ACTIVE", "SAMPLERBUFFER", "FILTER", "IMAGE1D", "IMAGE2D", "IMAGE3D",
- "IMAGECUBE", "IMAGE1DARRAY", "IMAGE2DARRAY", "IIMAGE1D", "IIMAGE2D",
- "IIMAGE3D", "IIMAGECUBE", "IIMAGE1DARRAY", "IIMAGE2DARRAY", "UIMAGE1D",
- "UIMAGE2D", "UIMAGE3D", "UIMAGECUBE", "UIMAGE1DARRAY", "UIMAGE2DARRAY",
- "IMAGE1DSHADOW", "IMAGE2DSHADOW", "IMAGEBUFFER", "IIMAGEBUFFER",
- "UIMAGEBUFFER", "IMAGE1DARRAYSHADOW", "IMAGE2DARRAYSHADOW", "ROW_MAJOR",
- "'('", "')'", "'['", "']'", "'.'", "','", "'+'", "'-'", "'!'", "'~'",
- "'*'", "'/'", "'%'", "'<'", "'>'", "'&'", "'^'", "'|'", "'?'", "':'",
- "'='", "';'", "'{'", "'}'", "$accept", "translation_unit", "$@1",
- "version_statement", "pragma_statement", "extension_statement_list",
- "extension_statement", "external_declaration_list",
- "variable_identifier", "primary_expression", "postfix_expression",
- "integer_expression", "function_call", "function_call_or_method",
- "function_call_generic", "function_call_header_no_parameters",
- "function_call_header_with_parameters", "function_call_header",
- "function_identifier", "unary_expression", "unary_operator",
- "multiplicative_expression", "additive_expression", "shift_expression",
- "relational_expression", "equality_expression", "and_expression",
- "exclusive_or_expression", "inclusive_or_expression",
- "logical_and_expression", "logical_xor_expression",
- "logical_or_expression", "conditional_expression",
- "assignment_expression", "assignment_operator", "expression",
- "constant_expression", "declaration", "function_prototype",
- "function_declarator", "function_header_with_parameters",
- "function_header", "parameter_declarator", "parameter_declaration",
- "parameter_qualifier", "parameter_type_specifier",
- "init_declarator_list", "single_declaration", "fully_specified_type",
- "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id",
- "interpolation_qualifier", "parameter_type_qualifier", "type_qualifier",
- "storage_qualifier", "type_specifier", "type_specifier_no_prec",
- "type_specifier_nonarray", "basic_type_specifier_nonarray",
- "precision_qualifier", "struct_specifier", "struct_declaration_list",
- "struct_declaration", "struct_declarator_list", "struct_declarator",
- "initializer", "declaration_statement", "statement", "simple_statement",
- "compound_statement", "statement_no_new_scope",
- "compound_statement_no_new_scope", "statement_list",
- "expression_statement", "selection_statement",
- "selection_rest_statement", "condition", "switch_statement",
- "case_label", "iteration_statement", "for_init_statement",
- "conditionopt", "for_rest_statement", "jump_statement",
- "external_declaration", "function_definition", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const yytype_uint16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
- 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
- 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
- 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
- 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
- 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
- 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
- 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
- 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
- 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
- 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
- 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
- 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,
- 415, 416, 417, 418, 419, 420, 421, 422, 423, 424,
- 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
- 435, 436, 437, 438, 439, 440, 441, 442, 443, 444,
- 445, 446, 447, 448, 40, 41, 91, 93, 46, 44,
- 43, 45, 33, 126, 42, 47, 37, 60, 62, 38,
- 94, 124, 63, 58, 61, 59, 123, 125
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint16 yyr1[] =
-{
- 0, 218, 220, 219, 221, 221, 222, 222, 222, 222,
- 222, 223, 223, 224, 225, 225, 226, 227, 227, 227,
- 227, 227, 227, 228, 228, 228, 228, 228, 228, 229,
- 230, 231, 231, 232, 232, 233, 233, 234, 234, 235,
- 236, 236, 236, 237, 237, 237, 237, 238, 238, 238,
- 238, 239, 239, 239, 239, 240, 240, 240, 241, 241,
- 241, 242, 242, 242, 242, 242, 243, 243, 243, 244,
- 244, 245, 245, 246, 246, 247, 247, 248, 248, 249,
- 249, 250, 250, 251, 251, 252, 252, 252, 252, 252,
- 252, 252, 252, 252, 252, 252, 253, 253, 254, 255,
- 255, 255, 256, 257, 257, 258, 258, 259, 260, 260,
- 261, 261, 261, 261, 262, 262, 262, 262, 263, 264,
- 264, 264, 264, 264, 264, 264, 265, 265, 265, 265,
- 265, 265, 265, 265, 266, 266, 267, 268, 268, 269,
- 269, 270, 270, 270, 271, 272, 272, 272, 272, 272,
- 272, 272, 272, 273, 273, 273, 273, 273, 273, 273,
- 273, 273, 274, 274, 275, 275, 275, 276, 276, 276,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 278, 278, 278, 279, 279, 280, 280, 281, 282,
- 282, 283, 283, 284, 285, 286, 286, 287, 287, 287,
- 287, 287, 287, 287, 288, 288, 289, 289, 290, 290,
- 291, 291, 292, 292, 293, 294, 294, 295, 295, 296,
- 297, 297, 298, 298, 298, 299, 299, 300, 300, 301,
- 301, 302, 302, 302, 302, 302, 303, 303, 303, 304
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 0, 4, 0, 3, 2, 2, 2, 2,
- 2, 0, 2, 5, 1, 2, 1, 1, 1, 1,
- 1, 1, 3, 1, 4, 1, 3, 2, 2, 1,
- 1, 1, 3, 2, 2, 2, 1, 2, 3, 2,
- 1, 1, 1, 1, 2, 2, 2, 1, 1, 1,
- 1, 1, 3, 3, 3, 1, 3, 3, 1, 3,
- 3, 1, 3, 3, 3, 3, 1, 3, 3, 1,
- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 5, 1, 3, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 1, 2,
- 2, 4, 2, 1, 1, 2, 3, 3, 2, 5,
- 3, 2, 3, 2, 0, 1, 1, 1, 1, 1,
- 3, 5, 6, 7, 8, 5, 1, 2, 4, 5,
- 6, 7, 4, 2, 1, 2, 4, 1, 3, 1,
- 3, 1, 1, 1, 1, 1, 1, 2, 1, 2,
- 2, 3, 1, 1, 1, 1, 2, 1, 1, 2,
- 2, 1, 1, 2, 1, 3, 4, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 5, 4, 1, 2, 3, 1,
- 3, 1, 4, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 2, 3, 1, 1, 2, 3,
- 1, 2, 1, 2, 5, 3, 1, 1, 4, 5,
- 3, 2, 5, 7, 6, 1, 1, 1, 0, 2,
- 3, 2, 2, 2, 3, 2, 1, 1, 1, 2
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint16 yydefact[] =
-{
- 4, 0, 0, 11, 0, 1, 2, 5, 0, 0,
- 12, 0, 154, 153, 174, 171, 172, 173, 178, 179,
- 180, 181, 182, 183, 184, 185, 186, 175, 176, 177,
- 0, 157, 158, 161, 155, 143, 142, 141, 187, 188,
- 189, 190, 191, 192, 193, 194, 195, 196, 197, 199,
- 200, 201, 202, 204, 205, 206, 207, 208, 209, 210,
- 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
- 0, 170, 169, 152, 223, 222, 221, 0, 0, 0,
- 0, 0, 0, 0, 198, 203, 278, 3, 277, 0,
- 0, 104, 114, 0, 119, 126, 146, 148, 0, 145,
- 134, 162, 164, 167, 0, 168, 14, 276, 0, 159,
- 160, 156, 0, 0, 133, 0, 150, 0, 6, 7,
- 8, 9, 10, 0, 15, 99, 0, 279, 102, 114,
- 144, 115, 116, 117, 105, 0, 114, 0, 100, 127,
- 147, 149, 135, 0, 163, 0, 0, 0, 0, 226,
- 151, 0, 139, 0, 137, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 16, 20, 18, 19,
- 21, 42, 0, 0, 0, 47, 48, 49, 50, 252,
- 0, 248, 17, 23, 43, 25, 30, 31, 0, 0,
- 36, 0, 51, 0, 55, 58, 61, 66, 69, 71,
- 73, 75, 77, 79, 81, 83, 96, 0, 234, 0,
- 134, 237, 250, 236, 235, 0, 238, 239, 240, 241,
- 242, 243, 106, 111, 113, 118, 0, 120, 107, 0,
- 0, 165, 51, 98, 0, 40, 13, 0, 231, 0,
- 229, 225, 227, 101, 0, 136, 0, 272, 271, 0,
- 0, 0, 275, 273, 0, 0, 0, 261, 0, 44,
- 45, 0, 244, 0, 27, 28, 0, 0, 34, 33,
- 0, 170, 37, 39, 86, 87, 89, 88, 91, 92,
- 93, 94, 95, 90, 85, 0, 46, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 253, 249,
- 251, 108, 110, 112, 0, 0, 128, 0, 233, 132,
- 166, 224, 0, 0, 228, 140, 138, 0, 266, 265,
- 268, 0, 274, 0, 260, 152, 257, 0, 0, 22,
- 245, 0, 29, 26, 32, 38, 84, 52, 53, 54,
- 56, 57, 59, 60, 64, 65, 62, 63, 67, 68,
- 70, 72, 74, 76, 78, 80, 0, 97, 0, 121,
- 0, 125, 0, 129, 0, 230, 0, 267, 0, 0,
- 0, 0, 0, 0, 24, 0, 0, 0, 122, 130,
- 0, 232, 0, 269, 0, 256, 254, 259, 0, 247,
- 262, 246, 82, 109, 123, 0, 131, 0, 270, 264,
- 0, 258, 124, 263, 255
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int16 yydefgoto[] =
-{
- -1, 2, 9, 3, 86, 6, 10, 87, 182, 183,
- 184, 341, 185, 186, 187, 188, 189, 190, 191, 192,
- 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
- 203, 204, 205, 206, 285, 207, 234, 208, 209, 90,
- 91, 92, 223, 134, 135, 224, 93, 94, 95, 96,
- 153, 154, 97, 136, 98, 99, 235, 101, 102, 103,
- 104, 105, 148, 149, 239, 240, 319, 211, 212, 213,
- 214, 400, 401, 215, 216, 217, 396, 338, 218, 219,
- 220, 330, 378, 379, 221, 106, 107
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -321
-static const yytype_int16 yypact[] =
-{
- -86, -57, 45, -321, -56, -321, -50, -321, -10, 3320,
- -321, -26, -321, -321, -321, -321, -321, -321, -321, -321,
- -321, -321, -321, -321, -321, -321, -321, -321, -321, -321,
- 79, -321, -321, -321, -321, -321, -321, -321, -321, -321,
- -321, -321, -321, -321, -321, -321, -321, -321, -321, -321,
- -321, -321, -321, -321, -321, -321, -321, -321, -321, -321,
- -321, -321, -321, -321, -321, -321, -321, -321, -321, -321,
- -70, -321, -321, 43, -321, -321, -321, 18, -22, -12,
- -5, 2, 25, -101, -321, -321, -321, 3320, -321, -43,
- -55, -54, 6, -148, -321, 52, 211, 211, 3509, -321,
- -321, -321, -47, -321, 3581, -321, -321, -321, 110, -321,
- -321, -321, -14, 3509, -321, 211, -321, 3581, -321, -321,
- -321, -321, -321, 131, -321, -321, 389, -321, -321, 15,
- -321, -321, -321, -321, -321, 3509, 109, 136, -321, -152,
- -321, -321, -321, 2400, -321, 105, 3509, 143, 1781, -321,
- -321, 7, 9, -107, -321, 10, 12, 1249, 27, 36,
- 17, 2015, 40, 2952, 22, 42, -65, -321, -321, -321,
- -321, -321, 2952, 2952, 2952, -321, -321, -321, -321, -321,
- 604, -321, -321, -321, -20, -321, -321, -321, 47, -92,
- 3136, 46, -67, 2952, -24, -16, 111, -73, 108, 37,
- 41, 39, 162, 161, -82, -321, -321, -147, -321, 44,
- 61, -321, -321, -321, -321, 819, -321, -321, -321, -321,
- -321, -321, -321, -321, -321, 181, 3509, -160, -321, 2584,
- 2952, -321, -321, -321, 63, -321, -321, 1898, 62, -146,
- -321, -321, -321, -321, 183, -321, 131, -321, -321, 187,
- 1664, 2952, -321, -321, -144, 2952, -140, -321, 2216, -321,
- -321, -81, -321, 1034, -321, -321, 2952, 3437, -321, -321,
- 2952, 70, -321, -321, -321, -321, -321, -321, -321, -321,
- -321, -321, -321, -321, -321, 2952, -321, 2952, 2952, 2952,
- 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952,
- 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, -321, -321,
- -321, 74, -321, -321, 2768, 2952, 64, 69, -321, -321,
- -321, -321, 2952, 143, -321, -321, -321, 82, -321, -321,
- 2216, -74, -321, -68, -321, 235, 78, 203, 85, -321,
- -321, 84, 78, 88, -321, -321, -321, -321, -321, -321,
- -24, -24, -16, -16, 111, 111, 111, 111, -73, -73,
- 108, 37, 41, 39, 162, 161, -129, -321, 2952, 71,
- 86, -321, 2952, 72, 87, -321, 2952, -321, 73, 92,
- 1249, 75, 76, 1463, -321, 2952, 95, 2952, 80, -321,
- 2952, -321, -63, 2952, 1463, 277, -321, -321, 2952, -321,
- -321, -321, -321, -321, -321, 2952, -321, 81, 78, -321,
- 1249, -321, -321, -321, -321
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int16 yypgoto[] =
-{
- -321, -321, -321, -321, -321, -321, -321, -321, -321, -321,
- -321, -321, -321, -321, 26, -321, -321, -321, -321, -135,
- -321, -91, -88, -106, -90, -3, -6, -4, -2, -1,
- 0, -321, -139, -174, -321, -156, -217, 11, 13, -321,
- -321, -321, 83, 170, 164, 89, -321, -321, -243, -321,
- -321, 56, -71, -321, -321, -72, -9, -32, -321, -321,
- 227, -321, 160, -131, -321, -15, -195, 57, -154, -320,
- -69, -84, 222, 133, 66, -321, -321, -13, -321, -321,
- -321, -321, -321, -321, -321, 231, -321
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -170
-static const yytype_int16 yytable[] =
-{
- 100, 116, 115, 249, 233, 254, 112, 256, 232, 305,
- 130, -169, 317, 294, 295, 337, 272, 242, 261, 130,
- 88, 4, 89, 1, 140, 141, 274, 275, 276, 277,
- 278, 279, 280, 281, 282, 283, 314, 259, 260, 131,
- 132, 133, 228, 150, 229, 5, 12, 13, 131, 132,
- 133, 137, 307, 323, 315, 307, 318, 7, 286, 307,
- 8, 310, 230, 399, 264, 265, 11, 138, 308, 324,
- 307, 332, 144, 334, 399, 30, 31, 32, 100, 33,
- 34, 35, 36, 37, 385, 151, 108, 337, 245, 142,
- 233, 118, 246, 123, 232, 331, 345, 370, 88, 333,
- 89, 119, 336, 269, 147, 374, 242, 270, 120, 310,
- 342, 346, 109, 110, 339, 121, 111, 210, 307, 114,
- 371, 380, 74, 75, 76, 307, 225, 381, 139, -41,
- 306, 307, 407, 367, 296, 297, 307, 147, 122, 147,
- 128, 318, 131, 132, 133, 129, 113, 284, 210, 143,
- 366, 386, 347, 348, 349, 232, 232, 232, 232, 232,
- 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
- 232, 210, 125, 126, 336, 233, 266, 389, 267, 232,
- 287, 288, 289, 233, 290, 291, 145, 232, 354, 355,
- 356, 357, 404, 292, 293, 406, 298, 299, 318, 350,
- 351, -103, 146, 411, 352, 353, 210, 152, 358, 359,
- 412, 402, 227, 318, 12, 13, 318, 225, 236, 238,
- 392, 250, 243, 244, 318, 247, 395, 248, 147, 233,
- 251, 318, 252, 232, 255, 257, 258, 408, 12, 13,
- 273, 210, 268, 30, 31, 32, 300, 33, 34, 210,
- 302, 301, 303, 304, 210, -40, 414, 311, 322, 125,
- 320, 325, 327, 116, 115, -35, 373, 30, 31, 32,
- 368, 33, 34, 35, 36, 37, 376, 307, 372, 382,
- 383, 384, -41, 388, 391, 387, 390, 394, 393, 410,
- 398, 180, 403, 344, 405, 361, 413, 360, 362, 222,
- 226, 363, 326, 364, 117, 365, 237, 328, 375, 312,
- 409, 127, 397, 263, 0, 313, 329, 377, 124, 0,
- 0, 210, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 210, 0, 0, 210, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 210, 0, 0, 0, 0,
- 0, 0, 12, 13, 14, 15, 16, 17, 155, 156,
- 157, 210, 158, 159, 160, 161, 162, 163, 164, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 32, 0, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 165, 166, 167, 168, 169, 170,
- 171, 0, 0, 172, 173, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 73, 74, 75, 76, 0, 77, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 83, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 84, 0, 85, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 174, 0, 0, 0, 0, 0, 175,
- 176, 177, 178, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 179, 180, 181, 12, 13, 14,
- 15, 16, 17, 155, 156, 157, 0, 158, 159, 160,
- 161, 162, 163, 164, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 0,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 165,
- 166, 167, 168, 169, 170, 171, 0, 0, 172, 173,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 73, 74, 75,
- 76, 0, 77, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 83, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,
- 0, 85, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 174, 0,
- 0, 0, 0, 0, 175, 176, 177, 178, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 179,
- 180, 262, 12, 13, 14, 15, 16, 17, 155, 156,
- 157, 0, 158, 159, 160, 161, 162, 163, 164, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 32, 0, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 165, 166, 167, 168, 169, 170,
- 171, 0, 0, 172, 173, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 73, 74, 75, 76, 0, 77, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 83, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 84, 0, 85, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 174, 0, 0, 0, 0, 0, 175,
- 176, 177, 178, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 179, 180, 309, 12, 13, 14,
- 15, 16, 17, 155, 156, 157, 0, 158, 159, 160,
- 161, 162, 163, 164, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 0,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 165,
- 166, 167, 168, 169, 170, 171, 0, 0, 172, 173,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 73, 74, 75,
- 76, 0, 77, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 83, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,
- 0, 85, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 174, 0,
- 0, 0, 0, 0, 175, 176, 177, 178, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 179,
- 180, 340, 12, 13, 14, 15, 16, 17, 155, 156,
- 157, 0, 158, 159, 160, 161, 162, 163, 164, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 32, 0, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 165, 166, 167, 168, 169, 170,
- 171, 0, 0, 172, 173, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 73, 74, 75, 76, 0, 77, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 83, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 84, 0, 85, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 174, 0, 0, 0, 0, 0, 175,
- 176, 177, 178, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 179, 180, 12, 13, 14, 15,
- 16, 17, 155, 156, 157, 0, 158, 159, 160, 161,
- 162, 163, 164, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 0, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 165, 166,
- 167, 168, 169, 170, 171, 0, 0, 172, 173, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 73, 74, 75, 76,
- 0, 77, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 83, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 84, 0,
- 85, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 174, 0, 0,
- 0, 0, 0, 175, 176, 177, 178, 12, 13, 14,
- 15, 16, 17, 0, 0, 0, 0, 0, 179, 126,
- 0, 0, 0, 0, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 0,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 0,
- 166, 167, 168, 169, 170, 171, 0, 0, 172, 173,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 73, 74, 75,
- 76, 0, 77, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 83, 14, 15, 16, 17,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 0, 0, 0, 0, 0, 0, 84,
- 0, 85, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 0, 72, 174, 0,
- 0, 0, 0, 0, 175, 176, 177, 178, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 179,
- 0, 0, 0, 0, 0, 74, 75, 76, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 14, 15, 16, 17, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 0, 0, 0, 0, 0, 0, 84, 0, 85, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 0, 72, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 241, 0,
- 0, 0, 74, 75, 76, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 14, 15, 16, 17, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 0, 0, 0,
- 0, 0, 0, 84, 0, 85, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 0, 166, 167, 168, 169, 170, 171, 0, 0, 172,
- 173, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 321, 0, 0, 0, 74,
- 75, 76, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 84, 0, 85, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 174,
- 0, 0, 0, 0, 0, 175, 176, 177, 178, 12,
- 13, 14, 15, 16, 17, 0, 0, 0, 0, 0,
- 253, 0, 0, 0, 0, 0, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 0, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 0, 166, 167, 168, 169, 170, 171, 0, 0,
- 172, 173, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 335,
- 74, 75, 76, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 83, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 84, 0, 85, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 14, 15, 16, 17, 0,
- 174, 0, 0, 0, 0, 0, 175, 176, 177, 178,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 0, 166, 167, 168, 169,
- 170, 171, 0, 0, 172, 173, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 74, 75, 76, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 84, 0, 85, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
- 15, 16, 17, 0, 174, 0, 0, 231, 0, 0,
- 175, 176, 177, 178, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 0,
- 166, 167, 168, 169, 170, 171, 0, 0, 172, 173,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 74, 75,
- 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,
- 0, 85, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 14, 15, 16, 17, 0, 174, 0,
- 0, 316, 0, 0, 175, 176, 177, 178, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 0, 166, 167, 168, 169, 170, 171,
- 0, 0, 172, 173, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 74, 75, 76, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 84, 0, 85, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 14, 15, 16,
- 17, 0, 174, 0, 0, 369, 0, 0, 175, 176,
- 177, 178, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 0, 166, 167,
- 168, 169, 170, 171, 0, 0, 172, 173, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 74, 75, 76, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 84, 0, 85,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 14, 15, 16, 17, 0, 174, 0, 0, 0,
- 0, 0, 175, 176, 177, 178, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 271, 0, 166, 167, 168, 169, 170, 171, 0, 0,
- 172, 173, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 74, 75, 76, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 84, 0, 85, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 12, 13, 14, 15, 16, 17, 0,
- 174, 0, 0, 0, 0, 0, 175, 176, 177, 178,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 0, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 0, 72, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 73, 74, 75, 76, 0, 77, 0,
- 0, 0, 0, 0, 0, 0, 78, 79, 80, 81,
- 82, 83, 14, 15, 16, 17, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 0,
- 0, 0, 0, 0, 0, 84, 0, 85, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 0, 343, 14, 15, 16, 17, 171, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 74, 75, 76, 0, 0, 0, 0, 0, 0,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 0, 72, 14, 15, 16, 17,
- 0, 0, 84, 0, 85, 0, 0, 0, 0, 0,
- 0, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 74, 75, 76, 0, 0, 0, 0,
- 0, 0, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 0, 72, 0, 0,
- 0, 0, 0, 0, 84, 0, 85, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 84, 0, 85
-};
-
-static const yytype_int16 yycheck[] =
-{
- 9, 73, 73, 157, 143, 161, 76, 163, 143, 91,
- 4, 76, 229, 86, 87, 258, 190, 148, 174, 4,
- 9, 78, 9, 109, 96, 97, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, 102, 196, 172, 173, 33,
- 34, 35, 194, 115, 196, 0, 3, 4, 33, 34,
- 35, 199, 199, 199, 214, 199, 230, 113, 193, 199,
- 110, 215, 214, 383, 84, 85, 76, 215, 215, 215,
- 199, 215, 104, 213, 394, 32, 33, 34, 87, 36,
- 37, 38, 39, 40, 213, 117, 112, 330, 195, 98,
- 229, 113, 199, 194, 229, 251, 270, 314, 87, 255,
- 87, 113, 258, 195, 113, 322, 237, 199, 113, 263,
- 266, 285, 33, 34, 195, 113, 37, 126, 199, 76,
- 315, 195, 104, 105, 106, 199, 135, 195, 76, 194,
- 212, 199, 195, 307, 207, 208, 199, 146, 113, 148,
- 195, 315, 33, 34, 35, 199, 216, 214, 157, 196,
- 306, 368, 287, 288, 289, 290, 291, 292, 293, 294,
- 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
- 305, 180, 215, 216, 330, 314, 196, 372, 198, 314,
- 204, 205, 206, 322, 200, 201, 76, 322, 294, 295,
- 296, 297, 387, 82, 83, 390, 88, 89, 372, 290,
- 291, 195, 216, 398, 292, 293, 215, 76, 298, 299,
- 405, 385, 76, 387, 3, 4, 390, 226, 113, 76,
- 376, 194, 215, 214, 398, 215, 380, 215, 237, 368,
- 194, 405, 215, 368, 194, 213, 194, 393, 3, 4,
- 194, 250, 195, 32, 33, 34, 209, 36, 37, 258,
- 211, 210, 90, 92, 263, 194, 410, 76, 196, 215,
- 197, 78, 75, 335, 335, 195, 197, 32, 33, 34,
- 196, 36, 37, 38, 39, 40, 194, 199, 214, 76,
- 195, 197, 194, 197, 197, 214, 214, 195, 215, 12,
- 214, 216, 197, 267, 214, 301, 215, 300, 302, 129,
- 136, 303, 246, 304, 77, 305, 146, 250, 323, 226,
- 394, 89, 381, 180, -1, 226, 250, 330, 87, -1,
- -1, 330, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 380, -1, -1, 383, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 394, -1, -1, -1, -1,
- -1, -1, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 410, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, -1, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- 81, -1, -1, 84, 85, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 103, 104, 105, 106, -1, 108, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 121, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 155, -1, 157, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 194, -1, -1, -1, -1, -1, 200,
- 201, 202, 203, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 215, 216, 217, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, -1, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, -1,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, -1, -1, 84, 85,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 103, 104, 105,
- 106, -1, 108, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 121, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 155,
- -1, 157, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 194, -1,
- -1, -1, -1, -1, 200, 201, 202, 203, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 215,
- 216, 217, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, -1, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, -1, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- 81, -1, -1, 84, 85, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 103, 104, 105, 106, -1, 108, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 121, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 155, -1, 157, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 194, -1, -1, -1, -1, -1, 200,
- 201, 202, 203, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 215, 216, 217, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, -1, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, -1,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, -1, -1, 84, 85,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 103, 104, 105,
- 106, -1, 108, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 121, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 155,
- -1, 157, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 194, -1,
- -1, -1, -1, -1, 200, 201, 202, 203, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 215,
- 216, 217, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, -1, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, -1, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- 81, -1, -1, 84, 85, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 103, 104, 105, 106, -1, 108, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 121, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 155, -1, 157, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 194, -1, -1, -1, -1, -1, 200,
- 201, 202, 203, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 215, 216, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, -1, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, -1, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, -1, -1, 84, 85, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 103, 104, 105, 106,
- -1, 108, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 121, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 155, -1,
- 157, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 194, -1, -1,
- -1, -1, -1, 200, 201, 202, 203, 3, 4, 5,
- 6, 7, 8, -1, -1, -1, -1, -1, 215, 216,
- -1, -1, -1, -1, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, -1,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, -1,
- 76, 77, 78, 79, 80, 81, -1, -1, 84, 85,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 103, 104, 105,
- 106, -1, 108, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 121, 5, 6, 7, 8,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, -1, -1, -1, -1, -1, -1, 155,
- -1, 157, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, -1, 76, 194, -1,
- -1, -1, -1, -1, 200, 201, 202, 203, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 215,
- -1, -1, -1, -1, -1, 104, 105, 106, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 5, 6, 7, 8, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- -1, -1, -1, -1, -1, -1, 155, -1, 157, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, -1, 76, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 217, -1,
- -1, -1, 104, 105, 106, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 5, 6, 7, 8, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, -1, -1, -1,
- -1, -1, -1, 155, -1, 157, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- -1, 76, 77, 78, 79, 80, 81, -1, -1, 84,
- 85, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 217, -1, -1, -1, 104,
- 105, 106, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 155, -1, 157, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 194,
- -1, -1, -1, -1, -1, 200, 201, 202, 203, 3,
- 4, 5, 6, 7, 8, -1, -1, -1, -1, -1,
- 215, -1, -1, -1, -1, -1, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, -1, 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, -1, 76, 77, 78, 79, 80, 81, -1, -1,
- 84, 85, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 103,
- 104, 105, 106, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 121, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 155, -1, 157, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 5, 6, 7, 8, -1,
- 194, -1, -1, -1, -1, -1, 200, 201, 202, 203,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, -1, 76, 77, 78, 79,
- 80, 81, -1, -1, 84, 85, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 104, 105, 106, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 155, -1, 157, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 5,
- 6, 7, 8, -1, 194, -1, -1, 197, -1, -1,
- 200, 201, 202, 203, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, -1,
- 76, 77, 78, 79, 80, 81, -1, -1, 84, 85,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 104, 105,
- 106, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 155,
- -1, 157, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 5, 6, 7, 8, -1, 194, -1,
- -1, 197, -1, -1, 200, 201, 202, 203, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, -1, 76, 77, 78, 79, 80, 81,
- -1, -1, 84, 85, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 104, 105, 106, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 155, -1, 157, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 5, 6, 7,
- 8, -1, 194, -1, -1, 197, -1, -1, 200, 201,
- 202, 203, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, -1, 76, 77,
- 78, 79, 80, 81, -1, -1, 84, 85, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 104, 105, 106, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 155, -1, 157,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 5, 6, 7, 8, -1, 194, -1, -1, -1,
- -1, -1, 200, 201, 202, 203, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, -1, 76, 77, 78, 79, 80, 81, -1, -1,
- 84, 85, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 104, 105, 106, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 155, -1, 157, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 3, 4, 5, 6, 7, 8, -1,
- 194, -1, -1, -1, -1, -1, 200, 201, 202, 203,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, -1, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, -1, 76, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 103, 104, 105, 106, -1, 108, -1,
- -1, -1, -1, -1, -1, -1, 116, 117, 118, 119,
- 120, 121, 5, 6, 7, 8, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, -1,
- -1, -1, -1, -1, -1, 155, -1, 157, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, -1, 76, 5, 6, 7, 8, 81, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 104, 105, 106, -1, -1, -1, -1, -1, -1,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, -1, 76, 5, 6, 7, 8,
- -1, -1, 155, -1, 157, -1, -1, -1, -1, -1,
- -1, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 104, 105, 106, -1, -1, -1, -1,
- -1, -1, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, -1, 76, -1, -1,
- -1, -1, -1, -1, 155, -1, 157, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 155, -1, 157
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const yytype_uint16 yystos[] =
-{
- 0, 109, 219, 221, 78, 0, 223, 113, 110, 220,
- 224, 76, 3, 4, 5, 6, 7, 8, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 76, 103, 104, 105, 106, 108, 116, 117,
- 118, 119, 120, 121, 155, 157, 222, 225, 255, 256,
- 257, 258, 259, 264, 265, 266, 267, 270, 272, 273,
- 274, 275, 276, 277, 278, 279, 303, 304, 112, 33,
- 34, 37, 76, 216, 76, 270, 273, 278, 113, 113,
- 113, 113, 113, 194, 303, 215, 216, 290, 195, 199,
- 4, 33, 34, 35, 261, 262, 271, 199, 215, 76,
- 273, 273, 274, 196, 275, 76, 216, 274, 280, 281,
- 273, 275, 76, 268, 269, 9, 10, 11, 13, 14,
- 15, 16, 17, 18, 19, 75, 76, 77, 78, 79,
- 80, 81, 84, 85, 194, 200, 201, 202, 203, 215,
- 216, 217, 226, 227, 228, 230, 231, 232, 233, 234,
- 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
- 245, 246, 247, 248, 249, 250, 251, 253, 255, 256,
- 274, 285, 286, 287, 288, 291, 292, 293, 296, 297,
- 298, 302, 261, 260, 263, 274, 262, 76, 194, 196,
- 214, 197, 237, 250, 254, 274, 113, 280, 76, 282,
- 283, 217, 281, 215, 214, 195, 199, 215, 215, 286,
- 194, 194, 215, 215, 253, 194, 253, 213, 194, 237,
- 237, 253, 217, 291, 84, 85, 196, 198, 195, 195,
- 199, 74, 251, 194, 93, 94, 95, 96, 97, 98,
- 99, 100, 101, 102, 214, 252, 237, 204, 205, 206,
- 200, 201, 82, 83, 86, 87, 207, 208, 88, 89,
- 209, 210, 211, 90, 92, 91, 212, 199, 215, 217,
- 286, 76, 260, 263, 196, 214, 197, 254, 251, 284,
- 197, 217, 196, 199, 215, 78, 269, 75, 285, 292,
- 299, 253, 215, 253, 213, 103, 253, 266, 295, 195,
- 217, 229, 253, 76, 232, 251, 251, 237, 237, 237,
- 239, 239, 240, 240, 241, 241, 241, 241, 242, 242,
- 243, 244, 245, 246, 247, 248, 253, 251, 196, 197,
- 254, 284, 214, 197, 254, 283, 194, 295, 300, 301,
- 195, 195, 76, 195, 197, 213, 254, 214, 197, 284,
- 214, 197, 253, 215, 195, 286, 294, 288, 214, 287,
- 289, 290, 251, 197, 284, 214, 284, 195, 253, 289,
- 12, 284, 284, 215, 286
-};
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-
-#define YYFAIL goto yyerrlab
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (0))
-
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval, &yylloc, scanner)
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value, Location, state); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
- YYLTYPE const * const yylocationp;
- struct _mesa_glsl_parse_state *state;
-#endif
-{
- if (!yyvaluep)
- return;
- YYUSE (yylocationp);
- YYUSE (state);
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
-# endif
- switch (yytype)
- {
- default:
- break;
- }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
- YYLTYPE const * const yylocationp;
- struct _mesa_glsl_parse_state *state;
-#endif
-{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- YY_LOCATION_PRINT (yyoutput, *yylocationp);
- YYFPRINTF (yyoutput, ": ");
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state);
- YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (; yybottom <= yytop; yybottom++)
- {
- int yybot = *yybottom;
- YYFPRINTF (stderr, " %d", yybot);
- }
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct _mesa_glsl_parse_state *state)
-#else
-static void
-yy_reduce_print (yyvsp, yylsp, yyrule, state)
- YYSTYPE *yyvsp;
- YYLTYPE *yylsp;
- int yyrule;
- struct _mesa_glsl_parse_state *state;
-#endif
-{
- int yynrhs = yyr2[yyrule];
- int yyi;
- unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
- /* The symbols being reduced. */
- for (yyi = 0; yyi < yynrhs; yyi++)
- {
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- , &(yylsp[(yyi + 1) - (yynrhs)]) , state);
- YYFPRINTF (stderr, "\n");
- }
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, yylsp, Rule, state); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
-{
- YYSIZE_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- YYSIZE_T yyn = 0;
- char const *yyp = yystr;
-
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (! yyres)
- return yystrlen (yystr);
-
- return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
-
- if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
- return 0;
- else
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
-
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
-
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
-
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
- }
-}
-#endif /* YYERROR_VERBOSE */
-
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct _mesa_glsl_parse_state *state)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, yylocationp, state)
- const char *yymsg;
- int yytype;
- YYSTYPE *yyvaluep;
- YYLTYPE *yylocationp;
- struct _mesa_glsl_parse_state *state;
-#endif
-{
- YYUSE (yyvaluep);
- YYUSE (yylocationp);
- YYUSE (state);
-
- if (!yymsg)
- yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
- switch (yytype)
- {
-
- default:
- break;
- }
-}
-
-/* Prevent warnings from -Wmissing-prototypes. */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (struct _mesa_glsl_parse_state *state);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-
-
-/*-------------------------.
-| yyparse or yypush_parse. |
-`-------------------------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (struct _mesa_glsl_parse_state *state)
-#else
-int
-yyparse (state)
- struct _mesa_glsl_parse_state *state;
-#endif
-#endif
-{
-/* The lookahead symbol. */
-int yychar;
-
-/* The semantic value of the lookahead symbol. */
-YYSTYPE yylval;
-
-/* Location data for the lookahead symbol. */
-YYLTYPE yylloc;
-
- /* Number of syntax errors so far. */
- int yynerrs;
-
- int yystate;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
-
- /* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
- `yyls': related to locations.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs;
- YYSTYPE *yyvsp;
-
- /* The location stack. */
- YYLTYPE yylsa[YYINITDEPTH];
- YYLTYPE *yyls;
- YYLTYPE *yylsp;
-
- /* The locations where the error started and ended. */
- YYLTYPE yyerror_range[2];
-
- YYSIZE_T yystacksize;
-
- int yyn;
- int yyresult;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken;
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
- YYLTYPE yyloc;
-
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
- /* The number of symbols on the RHS of the reduced rule.
- Keep to zero when no symbol should be popped. */
- int yylen = 0;
-
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
- yyls = yylsa;
- yystacksize = YYINITDEPTH;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
- yyssp = yyss;
- yyvsp = yyvs;
- yylsp = yyls;
-
-#if YYLTYPE_IS_TRIVIAL
- /* Initialize the default location before parsing starts. */
- yylloc.first_line = yylloc.last_line = 1;
- yylloc.first_column = yylloc.last_column = 1;
-#endif
-
-/* User initialization code. */
-
-/* Line 1242 of yacc.c */
-#line 41 "glsl_parser.ypp"
-{
- yylloc.first_line = 1;
- yylloc.first_column = 1;
- yylloc.last_line = 1;
- yylloc.last_column = 1;
- yylloc.source = 0;
-}
-
-/* Line 1242 of yacc.c */
-#line 2632 "glsl_parser.cpp"
- yylsp[0] = yylloc;
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
- YYLTYPE *yyls1 = yyls;
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yyls1, yysize * sizeof (*yylsp),
- &yystacksize);
-
- yyls = yyls1;
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
- YYSTACK_RELOCATE (yyls_alloc, yyls);
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
- yylsp = yyls + yysize - 1;
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- if (yystate == YYFINAL)
- YYACCEPT;
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
- /* Do appropriate processing given the current state. Read a
- lookahead token if we need one and don't already have one. */
-
- /* First try to decide what to do without reference to lookahead token. */
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- /* Shift the lookahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
- /* Discard the shifted token. */
- yychar = YYEMPTY;
-
- yystate = yyn;
- *++yyvsp = yylval;
- *++yylsp = yylloc;
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
- /* Default location. */
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 2:
-
-/* Line 1455 of yacc.c */
-#line 213 "glsl_parser.ypp"
- {
- _mesa_glsl_initialize_types(state);
- ;}
- break;
-
- case 5:
-
-/* Line 1455 of yacc.c */
-#line 222 "glsl_parser.ypp"
- {
- switch ((yyvsp[(2) - (3)].n)) {
- case 100:
- state->es_shader = true;
- case 110:
- case 120:
- case 130:
- /* FINISHME: Check against implementation support versions. */
- state->language_version = (yyvsp[(2) - (3)].n);
- state->version_string =
- talloc_asprintf(state, "GLSL%s %d.%02d",
- state->es_shader ? " ES" : "",
- state->language_version / 100,
- state->language_version % 100);
- break;
- default:
- _mesa_glsl_error(& (yylsp[(2) - (3)]), state, "Shading language version"
- "%u is not supported\n", (yyvsp[(2) - (3)].n));
- break;
- }
- ;}
- break;
-
- case 10:
-
-/* Line 1455 of yacc.c */
-#line 251 "glsl_parser.ypp"
- {
- if (state->language_version < 120) {
- _mesa_glsl_warning(& (yylsp[(1) - (2)]), state,
- "pragma `invariant(all)' not supported in %s",
- state->version_string);
- } else {
- state->all_invariant = true;
- }
- ;}
- break;
-
- case 13:
-
-/* Line 1455 of yacc.c */
-#line 269 "glsl_parser.ypp"
- {
- if (!_mesa_glsl_process_extension((yyvsp[(2) - (5)].identifier), & (yylsp[(2) - (5)]), (yyvsp[(4) - (5)].identifier), & (yylsp[(4) - (5)]), state)) {
- YYERROR;
- }
- ;}
- break;
-
- case 14:
-
-/* Line 1455 of yacc.c */
-#line 278 "glsl_parser.ypp"
- {
- /* FINISHME: The NULL test is only required because 'precision'
- * FINISHME: statements are not yet supported.
- */
- if ((yyvsp[(1) - (1)].node) != NULL)
- state->translation_unit.push_tail(& (yyvsp[(1) - (1)].node)->link);
- ;}
- break;
-
- case 15:
-
-/* Line 1455 of yacc.c */
-#line 286 "glsl_parser.ypp"
- {
- /* FINISHME: The NULL test is only required because 'precision'
- * FINISHME: statements are not yet supported.
- */
- if ((yyvsp[(2) - (2)].node) != NULL)
- state->translation_unit.push_tail(& (yyvsp[(2) - (2)].node)->link);
- ;}
- break;
-
- case 17:
-
-/* Line 1455 of yacc.c */
-#line 301 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->primary_expression.identifier = (yyvsp[(1) - (1)].identifier);
- ;}
- break;
-
- case 18:
-
-/* Line 1455 of yacc.c */
-#line 308 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->primary_expression.int_constant = (yyvsp[(1) - (1)].n);
- ;}
- break;
-
- case 19:
-
-/* Line 1455 of yacc.c */
-#line 315 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->primary_expression.uint_constant = (yyvsp[(1) - (1)].n);
- ;}
- break;
-
- case 20:
-
-/* Line 1455 of yacc.c */
-#line 322 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->primary_expression.float_constant = (yyvsp[(1) - (1)].real);
- ;}
- break;
-
- case 21:
-
-/* Line 1455 of yacc.c */
-#line 329 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->primary_expression.bool_constant = (yyvsp[(1) - (1)].n);
- ;}
- break;
-
- case 22:
-
-/* Line 1455 of yacc.c */
-#line 336 "glsl_parser.ypp"
- {
- (yyval.expression) = (yyvsp[(2) - (3)].expression);
- ;}
- break;
-
- case 24:
-
-/* Line 1455 of yacc.c */
-#line 344 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_array_index, (yyvsp[(1) - (4)].expression), (yyvsp[(3) - (4)].expression), NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 25:
-
-/* Line 1455 of yacc.c */
-#line 350 "glsl_parser.ypp"
- {
- (yyval.expression) = (yyvsp[(1) - (1)].expression);
- ;}
- break;
-
- case 26:
-
-/* Line 1455 of yacc.c */
-#line 354 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->primary_expression.identifier = (yyvsp[(3) - (3)].identifier);
- ;}
- break;
-
- case 27:
-
-/* Line 1455 of yacc.c */
-#line 361 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_post_inc, (yyvsp[(1) - (2)].expression), NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 28:
-
-/* Line 1455 of yacc.c */
-#line 367 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_post_dec, (yyvsp[(1) - (2)].expression), NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 32:
-
-/* Line 1455 of yacc.c */
-#line 385 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 37:
-
-/* Line 1455 of yacc.c */
-#line 404 "glsl_parser.ypp"
- {
- (yyval.expression) = (yyvsp[(1) - (2)].expression);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->expressions.push_tail(& (yyvsp[(2) - (2)].expression)->link);
- ;}
- break;
-
- case 38:
-
-/* Line 1455 of yacc.c */
-#line 410 "glsl_parser.ypp"
- {
- (yyval.expression) = (yyvsp[(1) - (3)].expression);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link);
- ;}
- break;
-
- case 40:
-
-/* Line 1455 of yacc.c */
-#line 426 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_function_expression((yyvsp[(1) - (1)].type_specifier));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 41:
-
-/* Line 1455 of yacc.c */
-#line 432 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier));
- (yyval.expression) = new(ctx) ast_function_expression(callee);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 42:
-
-/* Line 1455 of yacc.c */
-#line 439 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier));
- (yyval.expression) = new(ctx) ast_function_expression(callee);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 44:
-
-/* Line 1455 of yacc.c */
-#line 451 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_pre_inc, (yyvsp[(2) - (2)].expression), NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 45:
-
-/* Line 1455 of yacc.c */
-#line 457 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_pre_dec, (yyvsp[(2) - (2)].expression), NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 46:
-
-/* Line 1455 of yacc.c */
-#line 463 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].expression), NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 47:
-
-/* Line 1455 of yacc.c */
-#line 472 "glsl_parser.ypp"
- { (yyval.n) = ast_plus; ;}
- break;
-
- case 48:
-
-/* Line 1455 of yacc.c */
-#line 473 "glsl_parser.ypp"
- { (yyval.n) = ast_neg; ;}
- break;
-
- case 49:
-
-/* Line 1455 of yacc.c */
-#line 474 "glsl_parser.ypp"
- { (yyval.n) = ast_logic_not; ;}
- break;
-
- case 50:
-
-/* Line 1455 of yacc.c */
-#line 475 "glsl_parser.ypp"
- { (yyval.n) = ast_bit_not; ;}
- break;
-
- case 52:
-
-/* Line 1455 of yacc.c */
-#line 481 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_mul, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 53:
-
-/* Line 1455 of yacc.c */
-#line 487 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_div, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 54:
-
-/* Line 1455 of yacc.c */
-#line 493 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_mod, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 56:
-
-/* Line 1455 of yacc.c */
-#line 503 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_add, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 57:
-
-/* Line 1455 of yacc.c */
-#line 509 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_sub, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 59:
-
-/* Line 1455 of yacc.c */
-#line 519 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_lshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 60:
-
-/* Line 1455 of yacc.c */
-#line 525 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_rshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 62:
-
-/* Line 1455 of yacc.c */
-#line 535 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_less, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 63:
-
-/* Line 1455 of yacc.c */
-#line 541 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_greater, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 64:
-
-/* Line 1455 of yacc.c */
-#line 547 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_lequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 65:
-
-/* Line 1455 of yacc.c */
-#line 553 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_gequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 67:
-
-/* Line 1455 of yacc.c */
-#line 563 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_equal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 68:
-
-/* Line 1455 of yacc.c */
-#line 569 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_nequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 70:
-
-/* Line 1455 of yacc.c */
-#line 579 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 72:
-
-/* Line 1455 of yacc.c */
-#line 589 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 74:
-
-/* Line 1455 of yacc.c */
-#line 599 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 76:
-
-/* Line 1455 of yacc.c */
-#line 609 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 78:
-
-/* Line 1455 of yacc.c */
-#line 619 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 80:
-
-/* Line 1455 of yacc.c */
-#line 629 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 82:
-
-/* Line 1455 of yacc.c */
-#line 639 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression(ast_conditional, (yyvsp[(1) - (5)].expression), (yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].expression));
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 84:
-
-/* Line 1455 of yacc.c */
-#line 649 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.expression) = new(ctx) ast_expression((yyvsp[(2) - (3)].n), (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL);
- (yyval.expression)->set_location(yylloc);
- ;}
- break;
-
- case 85:
-
-/* Line 1455 of yacc.c */
-#line 657 "glsl_parser.ypp"
- { (yyval.n) = ast_assign; ;}
- break;
-
- case 86:
-
-/* Line 1455 of yacc.c */
-#line 658 "glsl_parser.ypp"
- { (yyval.n) = ast_mul_assign; ;}
- break;
-
- case 87:
-
-/* Line 1455 of yacc.c */
-#line 659 "glsl_parser.ypp"
- { (yyval.n) = ast_div_assign; ;}
- break;
-
- case 88:
-
-/* Line 1455 of yacc.c */
-#line 660 "glsl_parser.ypp"
- { (yyval.n) = ast_mod_assign; ;}
- break;
-
- case 89:
-
-/* Line 1455 of yacc.c */
-#line 661 "glsl_parser.ypp"
- { (yyval.n) = ast_add_assign; ;}
- break;
-
- case 90:
-
-/* Line 1455 of yacc.c */
-#line 662 "glsl_parser.ypp"
- { (yyval.n) = ast_sub_assign; ;}
- break;
-
- case 91:
-
-/* Line 1455 of yacc.c */
-#line 663 "glsl_parser.ypp"
- { (yyval.n) = ast_ls_assign; ;}
- break;
-
- case 92:
-
-/* Line 1455 of yacc.c */
-#line 664 "glsl_parser.ypp"
- { (yyval.n) = ast_rs_assign; ;}
- break;
-
- case 93:
-
-/* Line 1455 of yacc.c */
-#line 665 "glsl_parser.ypp"
- { (yyval.n) = ast_and_assign; ;}
- break;
-
- case 94:
-
-/* Line 1455 of yacc.c */
-#line 666 "glsl_parser.ypp"
- { (yyval.n) = ast_xor_assign; ;}
- break;
-
- case 95:
-
-/* Line 1455 of yacc.c */
-#line 667 "glsl_parser.ypp"
- { (yyval.n) = ast_or_assign; ;}
- break;
-
- case 96:
-
-/* Line 1455 of yacc.c */
-#line 672 "glsl_parser.ypp"
- {
- (yyval.expression) = (yyvsp[(1) - (1)].expression);
- ;}
- break;
-
- case 97:
-
-/* Line 1455 of yacc.c */
-#line 676 "glsl_parser.ypp"
- {
- void *ctx = state;
- if ((yyvsp[(1) - (3)].expression)->oper != ast_sequence) {
- (yyval.expression) = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL);
- (yyval.expression)->set_location(yylloc);
- (yyval.expression)->expressions.push_tail(& (yyvsp[(1) - (3)].expression)->link);
- } else {
- (yyval.expression) = (yyvsp[(1) - (3)].expression);
- }
-
- (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link);
- ;}
- break;
-
- case 99:
-
-/* Line 1455 of yacc.c */
-#line 696 "glsl_parser.ypp"
- {
- (yyval.node) = (yyvsp[(1) - (2)].function);
- ;}
- break;
-
- case 100:
-
-/* Line 1455 of yacc.c */
-#line 700 "glsl_parser.ypp"
- {
- (yyval.node) = (yyvsp[(1) - (2)].declarator_list);
- ;}
- break;
-
- case 101:
-
-/* Line 1455 of yacc.c */
-#line 704 "glsl_parser.ypp"
- {
- if (((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_float)
- && ((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_int)) {
- _mesa_glsl_error(& (yylsp[(3) - (4)]), state, "global precision qualifier can "
- "only be applied to `int' or `float'\n");
- YYERROR;
- }
-
- (yyval.node) = NULL; /* FINISHME */
- ;}
- break;
-
- case 105:
-
-/* Line 1455 of yacc.c */
-#line 727 "glsl_parser.ypp"
- {
- (yyval.function) = (yyvsp[(1) - (2)].function);
- (yyval.function)->parameters.push_tail(& (yyvsp[(2) - (2)].parameter_declarator)->link);
- ;}
- break;
-
- case 106:
-
-/* Line 1455 of yacc.c */
-#line 732 "glsl_parser.ypp"
- {
- (yyval.function) = (yyvsp[(1) - (3)].function);
- (yyval.function)->parameters.push_tail(& (yyvsp[(3) - (3)].parameter_declarator)->link);
- ;}
- break;
-
- case 107:
-
-/* Line 1455 of yacc.c */
-#line 740 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.function) = new(ctx) ast_function();
- (yyval.function)->set_location(yylloc);
- (yyval.function)->return_type = (yyvsp[(1) - (3)].fully_specified_type);
- (yyval.function)->identifier = (yyvsp[(2) - (3)].identifier);
- ;}
- break;
-
- case 108:
-
-/* Line 1455 of yacc.c */
-#line 751 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
- (yyval.parameter_declarator)->set_location(yylloc);
- (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
- (yyval.parameter_declarator)->type->set_location(yylloc);
- (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (2)].type_specifier);
- (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (2)].identifier);
- ;}
- break;
-
- case 109:
-
-/* Line 1455 of yacc.c */
-#line 761 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
- (yyval.parameter_declarator)->set_location(yylloc);
- (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
- (yyval.parameter_declarator)->type->set_location(yylloc);
- (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (5)].type_specifier);
- (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (5)].identifier);
- (yyval.parameter_declarator)->is_array = true;
- (yyval.parameter_declarator)->array_size = (yyvsp[(4) - (5)].expression);
- ;}
- break;
-
- case 110:
-
-/* Line 1455 of yacc.c */
-#line 776 "glsl_parser.ypp"
- {
- (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i;
-
- (yyval.parameter_declarator) = (yyvsp[(3) - (3)].parameter_declarator);
- (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier);
- ;}
- break;
-
- case 111:
-
-/* Line 1455 of yacc.c */
-#line 783 "glsl_parser.ypp"
- {
- (yyval.parameter_declarator) = (yyvsp[(2) - (2)].parameter_declarator);
- (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier);
- ;}
- break;
-
- case 112:
-
-/* Line 1455 of yacc.c */
-#line 788 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i;
-
- (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
- (yyval.parameter_declarator)->set_location(yylloc);
- (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
- (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier);
- (yyval.parameter_declarator)->type->specifier = (yyvsp[(3) - (3)].type_specifier);
- ;}
- break;
-
- case 113:
-
-/* Line 1455 of yacc.c */
-#line 799 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
- (yyval.parameter_declarator)->set_location(yylloc);
- (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
- (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier);
- (yyval.parameter_declarator)->type->specifier = (yyvsp[(2) - (2)].type_specifier);
- ;}
- break;
-
- case 114:
-
-/* Line 1455 of yacc.c */
-#line 811 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- ;}
- break;
-
- case 115:
-
-/* Line 1455 of yacc.c */
-#line 815 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.in = 1;
- ;}
- break;
-
- case 116:
-
-/* Line 1455 of yacc.c */
-#line 820 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.out = 1;
- ;}
- break;
-
- case 117:
-
-/* Line 1455 of yacc.c */
-#line 825 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.in = 1;
- (yyval.type_qualifier).flags.q.out = 1;
- ;}
- break;
-
- case 120:
-
-/* Line 1455 of yacc.c */
-#line 839 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (3)].identifier), false, NULL, NULL);
- decl->set_location(yylloc);
-
- (yyval.declarator_list) = (yyvsp[(1) - (3)].declarator_list);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 121:
-
-/* Line 1455 of yacc.c */
-#line 848 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), true, NULL, NULL);
- decl->set_location(yylloc);
-
- (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 122:
-
-/* Line 1455 of yacc.c */
-#line 857 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (6)].identifier), true, (yyvsp[(5) - (6)].expression), NULL);
- decl->set_location(yylloc);
-
- (yyval.declarator_list) = (yyvsp[(1) - (6)].declarator_list);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 123:
-
-/* Line 1455 of yacc.c */
-#line 866 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (7)].identifier), true, NULL, (yyvsp[(7) - (7)].expression));
- decl->set_location(yylloc);
-
- (yyval.declarator_list) = (yyvsp[(1) - (7)].declarator_list);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 124:
-
-/* Line 1455 of yacc.c */
-#line 875 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (8)].identifier), true, (yyvsp[(5) - (8)].expression), (yyvsp[(8) - (8)].expression));
- decl->set_location(yylloc);
-
- (yyval.declarator_list) = (yyvsp[(1) - (8)].declarator_list);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 125:
-
-/* Line 1455 of yacc.c */
-#line 884 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), false, NULL, (yyvsp[(5) - (5)].expression));
- decl->set_location(yylloc);
-
- (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 126:
-
-/* Line 1455 of yacc.c */
-#line 897 "glsl_parser.ypp"
- {
- void *ctx = state;
- if ((yyvsp[(1) - (1)].fully_specified_type)->specifier->type_specifier != ast_struct) {
- _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "empty declaration list\n");
- YYERROR;
- } else {
- (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (1)].fully_specified_type));
- (yyval.declarator_list)->set_location(yylloc);
- }
- ;}
- break;
-
- case 127:
-
-/* Line 1455 of yacc.c */
-#line 908 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL);
-
- (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (2)].fully_specified_type));
- (yyval.declarator_list)->set_location(yylloc);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 128:
-
-/* Line 1455 of yacc.c */
-#line 917 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), true, NULL, NULL);
-
- (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type));
- (yyval.declarator_list)->set_location(yylloc);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 129:
-
-/* Line 1455 of yacc.c */
-#line 926 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (5)].identifier), true, (yyvsp[(4) - (5)].expression), NULL);
-
- (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (5)].fully_specified_type));
- (yyval.declarator_list)->set_location(yylloc);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 130:
-
-/* Line 1455 of yacc.c */
-#line 935 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (6)].identifier), true, NULL, (yyvsp[(6) - (6)].expression));
-
- (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (6)].fully_specified_type));
- (yyval.declarator_list)->set_location(yylloc);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 131:
-
-/* Line 1455 of yacc.c */
-#line 944 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (7)].identifier), true, (yyvsp[(4) - (7)].expression), (yyvsp[(7) - (7)].expression));
-
- (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (7)].fully_specified_type));
- (yyval.declarator_list)->set_location(yylloc);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 132:
-
-/* Line 1455 of yacc.c */
-#line 953 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression));
-
- (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type));
- (yyval.declarator_list)->set_location(yylloc);
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 133:
-
-/* Line 1455 of yacc.c */
-#line 962 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL);
-
- (yyval.declarator_list) = new(ctx) ast_declarator_list(NULL);
- (yyval.declarator_list)->set_location(yylloc);
- (yyval.declarator_list)->invariant = true;
-
- (yyval.declarator_list)->declarations.push_tail(&decl->link);
- ;}
- break;
-
- case 134:
-
-/* Line 1455 of yacc.c */
-#line 976 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type();
- (yyval.fully_specified_type)->set_location(yylloc);
- (yyval.fully_specified_type)->specifier = (yyvsp[(1) - (1)].type_specifier);
- ;}
- break;
-
- case 135:
-
-/* Line 1455 of yacc.c */
-#line 983 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type();
- (yyval.fully_specified_type)->set_location(yylloc);
- (yyval.fully_specified_type)->qualifier = (yyvsp[(1) - (2)].type_qualifier);
- (yyval.fully_specified_type)->specifier = (yyvsp[(2) - (2)].type_specifier);
- ;}
- break;
-
- case 136:
-
-/* Line 1455 of yacc.c */
-#line 994 "glsl_parser.ypp"
- {
- (yyval.type_qualifier) = (yyvsp[(3) - (4)].type_qualifier);
- ;}
- break;
-
- case 138:
-
-/* Line 1455 of yacc.c */
-#line 1002 "glsl_parser.ypp"
- {
- if (((yyvsp[(1) - (3)].type_qualifier).flags.i & (yyvsp[(3) - (3)].type_qualifier).flags.i) != 0) {
- _mesa_glsl_error(& (yylsp[(3) - (3)]), state,
- "duplicate layout qualifiers used\n");
- YYERROR;
- }
-
- (yyval.type_qualifier).flags.i = (yyvsp[(1) - (3)].type_qualifier).flags.i | (yyvsp[(3) - (3)].type_qualifier).flags.i;
-
- if ((yyvsp[(1) - (3)].type_qualifier).flags.q.explicit_location)
- (yyval.type_qualifier).location = (yyvsp[(1) - (3)].type_qualifier).location;
-
- if ((yyvsp[(3) - (3)].type_qualifier).flags.q.explicit_location)
- (yyval.type_qualifier).location = (yyvsp[(3) - (3)].type_qualifier).location;
- ;}
- break;
-
- case 139:
-
-/* Line 1455 of yacc.c */
-#line 1021 "glsl_parser.ypp"
- {
- bool got_one = false;
-
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
-
- if (state->ARB_fragment_coord_conventions_enable) {
- if (strcmp((yyvsp[(1) - (1)].identifier), "origin_upper_left") == 0) {
- got_one = true;
- (yyval.type_qualifier).flags.q.origin_upper_left = 1;
- } else if (strcmp((yyvsp[(1) - (1)].identifier), "pixel_center_integer") == 0) {
- got_one = true;
- (yyval.type_qualifier).flags.q.pixel_center_integer = 1;
- }
- }
-
- /* If the identifier didn't match any known layout identifiers,
- * emit an error.
- */
- if (!got_one) {
- _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "unrecognized layout identifier "
- "`%s'\n", (yyvsp[(1) - (1)].identifier));
- YYERROR;
- } else if (state->ARB_fragment_coord_conventions_warn) {
- _mesa_glsl_warning(& (yylsp[(1) - (1)]), state,
- "GL_ARB_fragment_coord_conventions layout "
- "identifier `%s' used\n", (yyvsp[(1) - (1)].identifier));
- }
- ;}
- break;
-
- case 140:
-
-/* Line 1455 of yacc.c */
-#line 1050 "glsl_parser.ypp"
- {
- bool got_one = false;
-
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
-
- if (state->ARB_explicit_attrib_location_enable) {
- /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
- * FINISHME: GLSL 1.30 (or later) are supported.
- */
- if (strcmp("location", (yyvsp[(1) - (3)].identifier)) == 0) {
- got_one = true;
-
- (yyval.type_qualifier).flags.q.explicit_location = 1;
-
- if ((yyvsp[(3) - (3)].n) >= 0) {
- (yyval.type_qualifier).location = (yyvsp[(3) - (3)].n);
- } else {
- _mesa_glsl_error(& (yylsp[(3) - (3)]), state,
- "invalid location %d specified\n", (yyvsp[(3) - (3)].n));
- YYERROR;
- }
- }
- }
-
- /* If the identifier didn't match any known layout identifiers,
- * emit an error.
- */
- if (!got_one) {
- _mesa_glsl_error(& (yylsp[(1) - (3)]), state, "unrecognized layout identifier "
- "`%s'\n", (yyvsp[(1) - (3)].identifier));
- YYERROR;
- } else if (state->ARB_explicit_attrib_location_warn) {
- _mesa_glsl_warning(& (yylsp[(1) - (3)]), state,
- "GL_ARB_explicit_attrib_location layout "
- "identifier `%s' used\n", (yyvsp[(1) - (3)].identifier));
- }
- ;}
- break;
-
- case 141:
-
-/* Line 1455 of yacc.c */
-#line 1091 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.smooth = 1;
- ;}
- break;
-
- case 142:
-
-/* Line 1455 of yacc.c */
-#line 1096 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.flat = 1;
- ;}
- break;
-
- case 143:
-
-/* Line 1455 of yacc.c */
-#line 1101 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.noperspective = 1;
- ;}
- break;
-
- case 144:
-
-/* Line 1455 of yacc.c */
-#line 1109 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.constant = 1;
- ;}
- break;
-
- case 147:
-
-/* Line 1455 of yacc.c */
-#line 1119 "glsl_parser.ypp"
- {
- (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier);
- (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i;
- ;}
- break;
-
- case 149:
-
-/* Line 1455 of yacc.c */
-#line 1125 "glsl_parser.ypp"
- {
- (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier);
- (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i;
- ;}
- break;
-
- case 150:
-
-/* Line 1455 of yacc.c */
-#line 1130 "glsl_parser.ypp"
- {
- (yyval.type_qualifier) = (yyvsp[(2) - (2)].type_qualifier);
- (yyval.type_qualifier).flags.q.invariant = 1;
- ;}
- break;
-
- case 151:
-
-/* Line 1455 of yacc.c */
-#line 1135 "glsl_parser.ypp"
- {
- (yyval.type_qualifier) = (yyvsp[(2) - (3)].type_qualifier);
- (yyval.type_qualifier).flags.i |= (yyvsp[(3) - (3)].type_qualifier).flags.i;
- (yyval.type_qualifier).flags.q.invariant = 1;
- ;}
- break;
-
- case 152:
-
-/* Line 1455 of yacc.c */
-#line 1141 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.invariant = 1;
- ;}
- break;
-
- case 153:
-
-/* Line 1455 of yacc.c */
-#line 1149 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.constant = 1;
- ;}
- break;
-
- case 154:
-
-/* Line 1455 of yacc.c */
-#line 1154 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.attribute = 1;
- ;}
- break;
-
- case 155:
-
-/* Line 1455 of yacc.c */
-#line 1159 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.varying = 1;
- ;}
- break;
-
- case 156:
-
-/* Line 1455 of yacc.c */
-#line 1164 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.centroid = 1;
- (yyval.type_qualifier).flags.q.varying = 1;
- ;}
- break;
-
- case 157:
-
-/* Line 1455 of yacc.c */
-#line 1170 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.in = 1;
- ;}
- break;
-
- case 158:
-
-/* Line 1455 of yacc.c */
-#line 1175 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.out = 1;
- ;}
- break;
-
- case 159:
-
-/* Line 1455 of yacc.c */
-#line 1180 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.in = 1;
- ;}
- break;
-
- case 160:
-
-/* Line 1455 of yacc.c */
-#line 1185 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.out = 1;
- ;}
- break;
-
- case 161:
-
-/* Line 1455 of yacc.c */
-#line 1190 "glsl_parser.ypp"
- {
- memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
- (yyval.type_qualifier).flags.q.uniform = 1;
- ;}
- break;
-
- case 163:
-
-/* Line 1455 of yacc.c */
-#line 1199 "glsl_parser.ypp"
- {
- (yyval.type_specifier) = (yyvsp[(2) - (2)].type_specifier);
- (yyval.type_specifier)->precision = (yyvsp[(1) - (2)].n);
- ;}
- break;
-
- case 165:
-
-/* Line 1455 of yacc.c */
-#line 1208 "glsl_parser.ypp"
- {
- (yyval.type_specifier) = (yyvsp[(1) - (3)].type_specifier);
- (yyval.type_specifier)->is_array = true;
- (yyval.type_specifier)->array_size = NULL;
- ;}
- break;
-
- case 166:
-
-/* Line 1455 of yacc.c */
-#line 1214 "glsl_parser.ypp"
- {
- (yyval.type_specifier) = (yyvsp[(1) - (4)].type_specifier);
- (yyval.type_specifier)->is_array = true;
- (yyval.type_specifier)->array_size = (yyvsp[(3) - (4)].expression);
- ;}
- break;
-
- case 167:
-
-/* Line 1455 of yacc.c */
-#line 1223 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].n));
- (yyval.type_specifier)->set_location(yylloc);
- ;}
- break;
-
- case 168:
-
-/* Line 1455 of yacc.c */
-#line 1229 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].struct_specifier));
- (yyval.type_specifier)->set_location(yylloc);
- ;}
- break;
-
- case 169:
-
-/* Line 1455 of yacc.c */
-#line 1235 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].identifier));
- (yyval.type_specifier)->set_location(yylloc);
- ;}
- break;
-
- case 170:
-
-/* Line 1455 of yacc.c */
-#line 1243 "glsl_parser.ypp"
- { (yyval.n) = ast_void; ;}
- break;
-
- case 171:
-
-/* Line 1455 of yacc.c */
-#line 1244 "glsl_parser.ypp"
- { (yyval.n) = ast_float; ;}
- break;
-
- case 172:
-
-/* Line 1455 of yacc.c */
-#line 1245 "glsl_parser.ypp"
- { (yyval.n) = ast_int; ;}
- break;
-
- case 173:
-
-/* Line 1455 of yacc.c */
-#line 1246 "glsl_parser.ypp"
- { (yyval.n) = ast_uint; ;}
- break;
-
- case 174:
-
-/* Line 1455 of yacc.c */
-#line 1247 "glsl_parser.ypp"
- { (yyval.n) = ast_bool; ;}
- break;
-
- case 175:
-
-/* Line 1455 of yacc.c */
-#line 1248 "glsl_parser.ypp"
- { (yyval.n) = ast_vec2; ;}
- break;
-
- case 176:
-
-/* Line 1455 of yacc.c */
-#line 1249 "glsl_parser.ypp"
- { (yyval.n) = ast_vec3; ;}
- break;
-
- case 177:
-
-/* Line 1455 of yacc.c */
-#line 1250 "glsl_parser.ypp"
- { (yyval.n) = ast_vec4; ;}
- break;
-
- case 178:
-
-/* Line 1455 of yacc.c */
-#line 1251 "glsl_parser.ypp"
- { (yyval.n) = ast_bvec2; ;}
- break;
-
- case 179:
-
-/* Line 1455 of yacc.c */
-#line 1252 "glsl_parser.ypp"
- { (yyval.n) = ast_bvec3; ;}
- break;
-
- case 180:
-
-/* Line 1455 of yacc.c */
-#line 1253 "glsl_parser.ypp"
- { (yyval.n) = ast_bvec4; ;}
- break;
-
- case 181:
-
-/* Line 1455 of yacc.c */
-#line 1254 "glsl_parser.ypp"
- { (yyval.n) = ast_ivec2; ;}
- break;
-
- case 182:
-
-/* Line 1455 of yacc.c */
-#line 1255 "glsl_parser.ypp"
- { (yyval.n) = ast_ivec3; ;}
- break;
-
- case 183:
-
-/* Line 1455 of yacc.c */
-#line 1256 "glsl_parser.ypp"
- { (yyval.n) = ast_ivec4; ;}
- break;
-
- case 184:
-
-/* Line 1455 of yacc.c */
-#line 1257 "glsl_parser.ypp"
- { (yyval.n) = ast_uvec2; ;}
- break;
-
- case 185:
-
-/* Line 1455 of yacc.c */
-#line 1258 "glsl_parser.ypp"
- { (yyval.n) = ast_uvec3; ;}
- break;
-
- case 186:
-
-/* Line 1455 of yacc.c */
-#line 1259 "glsl_parser.ypp"
- { (yyval.n) = ast_uvec4; ;}
- break;
-
- case 187:
-
-/* Line 1455 of yacc.c */
-#line 1260 "glsl_parser.ypp"
- { (yyval.n) = ast_mat2; ;}
- break;
-
- case 188:
-
-/* Line 1455 of yacc.c */
-#line 1261 "glsl_parser.ypp"
- { (yyval.n) = ast_mat2x3; ;}
- break;
-
- case 189:
-
-/* Line 1455 of yacc.c */
-#line 1262 "glsl_parser.ypp"
- { (yyval.n) = ast_mat2x4; ;}
- break;
-
- case 190:
-
-/* Line 1455 of yacc.c */
-#line 1263 "glsl_parser.ypp"
- { (yyval.n) = ast_mat3x2; ;}
- break;
-
- case 191:
-
-/* Line 1455 of yacc.c */
-#line 1264 "glsl_parser.ypp"
- { (yyval.n) = ast_mat3; ;}
- break;
-
- case 192:
-
-/* Line 1455 of yacc.c */
-#line 1265 "glsl_parser.ypp"
- { (yyval.n) = ast_mat3x4; ;}
- break;
-
- case 193:
-
-/* Line 1455 of yacc.c */
-#line 1266 "glsl_parser.ypp"
- { (yyval.n) = ast_mat4x2; ;}
- break;
-
- case 194:
-
-/* Line 1455 of yacc.c */
-#line 1267 "glsl_parser.ypp"
- { (yyval.n) = ast_mat4x3; ;}
- break;
-
- case 195:
-
-/* Line 1455 of yacc.c */
-#line 1268 "glsl_parser.ypp"
- { (yyval.n) = ast_mat4; ;}
- break;
-
- case 196:
-
-/* Line 1455 of yacc.c */
-#line 1269 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler1d; ;}
- break;
-
- case 197:
-
-/* Line 1455 of yacc.c */
-#line 1270 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler2d; ;}
- break;
-
- case 198:
-
-/* Line 1455 of yacc.c */
-#line 1271 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler2drect; ;}
- break;
-
- case 199:
-
-/* Line 1455 of yacc.c */
-#line 1272 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler3d; ;}
- break;
-
- case 200:
-
-/* Line 1455 of yacc.c */
-#line 1273 "glsl_parser.ypp"
- { (yyval.n) = ast_samplercube; ;}
- break;
-
- case 201:
-
-/* Line 1455 of yacc.c */
-#line 1274 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler1dshadow; ;}
- break;
-
- case 202:
-
-/* Line 1455 of yacc.c */
-#line 1275 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler2dshadow; ;}
- break;
-
- case 203:
-
-/* Line 1455 of yacc.c */
-#line 1276 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler2drectshadow; ;}
- break;
-
- case 204:
-
-/* Line 1455 of yacc.c */
-#line 1277 "glsl_parser.ypp"
- { (yyval.n) = ast_samplercubeshadow; ;}
- break;
-
- case 205:
-
-/* Line 1455 of yacc.c */
-#line 1278 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler1darray; ;}
- break;
-
- case 206:
-
-/* Line 1455 of yacc.c */
-#line 1279 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler2darray; ;}
- break;
-
- case 207:
-
-/* Line 1455 of yacc.c */
-#line 1280 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler1darrayshadow; ;}
- break;
-
- case 208:
-
-/* Line 1455 of yacc.c */
-#line 1281 "glsl_parser.ypp"
- { (yyval.n) = ast_sampler2darrayshadow; ;}
- break;
-
- case 209:
-
-/* Line 1455 of yacc.c */
-#line 1282 "glsl_parser.ypp"
- { (yyval.n) = ast_isampler1d; ;}
- break;
-
- case 210:
-
-/* Line 1455 of yacc.c */
-#line 1283 "glsl_parser.ypp"
- { (yyval.n) = ast_isampler2d; ;}
- break;
-
- case 211:
-
-/* Line 1455 of yacc.c */
-#line 1284 "glsl_parser.ypp"
- { (yyval.n) = ast_isampler3d; ;}
- break;
-
- case 212:
-
-/* Line 1455 of yacc.c */
-#line 1285 "glsl_parser.ypp"
- { (yyval.n) = ast_isamplercube; ;}
- break;
-
- case 213:
-
-/* Line 1455 of yacc.c */
-#line 1286 "glsl_parser.ypp"
- { (yyval.n) = ast_isampler1darray; ;}
- break;
-
- case 214:
-
-/* Line 1455 of yacc.c */
-#line 1287 "glsl_parser.ypp"
- { (yyval.n) = ast_isampler2darray; ;}
- break;
-
- case 215:
-
-/* Line 1455 of yacc.c */
-#line 1288 "glsl_parser.ypp"
- { (yyval.n) = ast_usampler1d; ;}
- break;
-
- case 216:
-
-/* Line 1455 of yacc.c */
-#line 1289 "glsl_parser.ypp"
- { (yyval.n) = ast_usampler2d; ;}
- break;
-
- case 217:
-
-/* Line 1455 of yacc.c */
-#line 1290 "glsl_parser.ypp"
- { (yyval.n) = ast_usampler3d; ;}
- break;
-
- case 218:
-
-/* Line 1455 of yacc.c */
-#line 1291 "glsl_parser.ypp"
- { (yyval.n) = ast_usamplercube; ;}
- break;
-
- case 219:
-
-/* Line 1455 of yacc.c */
-#line 1292 "glsl_parser.ypp"
- { (yyval.n) = ast_usampler1darray; ;}
- break;
-
- case 220:
-
-/* Line 1455 of yacc.c */
-#line 1293 "glsl_parser.ypp"
- { (yyval.n) = ast_usampler2darray; ;}
- break;
-
- case 221:
-
-/* Line 1455 of yacc.c */
-#line 1297 "glsl_parser.ypp"
- {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& (yylsp[(1) - (1)]), state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
-
- (yyval.n) = ast_precision_high;
- ;}
- break;
-
- case 222:
-
-/* Line 1455 of yacc.c */
-#line 1307 "glsl_parser.ypp"
- {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& (yylsp[(1) - (1)]), state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
-
- (yyval.n) = ast_precision_medium;
- ;}
- break;
-
- case 223:
-
-/* Line 1455 of yacc.c */
-#line 1317 "glsl_parser.ypp"
- {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& (yylsp[(1) - (1)]), state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
-
- (yyval.n) = ast_precision_low;
- ;}
- break;
-
- case 224:
-
-/* Line 1455 of yacc.c */
-#line 1331 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.struct_specifier) = new(ctx) ast_struct_specifier((yyvsp[(2) - (5)].identifier), (yyvsp[(4) - (5)].node));
- (yyval.struct_specifier)->set_location(yylloc);
- ;}
- break;
-
- case 225:
-
-/* Line 1455 of yacc.c */
-#line 1337 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.struct_specifier) = new(ctx) ast_struct_specifier(NULL, (yyvsp[(3) - (4)].node));
- (yyval.struct_specifier)->set_location(yylloc);
- ;}
- break;
-
- case 226:
-
-/* Line 1455 of yacc.c */
-#line 1346 "glsl_parser.ypp"
- {
- (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list);
- (yyvsp[(1) - (1)].declarator_list)->link.self_link();
- ;}
- break;
-
- case 227:
-
-/* Line 1455 of yacc.c */
-#line 1351 "glsl_parser.ypp"
- {
- (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node);
- (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link);
- ;}
- break;
-
- case 228:
-
-/* Line 1455 of yacc.c */
-#line 1359 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
- type->set_location(yylloc);
-
- type->specifier = (yyvsp[(1) - (3)].type_specifier);
- (yyval.declarator_list) = new(ctx) ast_declarator_list(type);
- (yyval.declarator_list)->set_location(yylloc);
-
- (yyval.declarator_list)->declarations.push_degenerate_list_at_head(& (yyvsp[(2) - (3)].declaration)->link);
- ;}
- break;
-
- case 229:
-
-/* Line 1455 of yacc.c */
-#line 1374 "glsl_parser.ypp"
- {
- (yyval.declaration) = (yyvsp[(1) - (1)].declaration);
- (yyvsp[(1) - (1)].declaration)->link.self_link();
- ;}
- break;
-
- case 230:
-
-/* Line 1455 of yacc.c */
-#line 1379 "glsl_parser.ypp"
- {
- (yyval.declaration) = (yyvsp[(1) - (3)].declaration);
- (yyval.declaration)->link.insert_before(& (yyvsp[(3) - (3)].declaration)->link);
- ;}
- break;
-
- case 231:
-
-/* Line 1455 of yacc.c */
-#line 1387 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (1)].identifier), false, NULL, NULL);
- (yyval.declaration)->set_location(yylloc);
- ;}
- break;
-
- case 232:
-
-/* Line 1455 of yacc.c */
-#line 1393 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (4)].identifier), true, (yyvsp[(3) - (4)].expression), NULL);
- (yyval.declaration)->set_location(yylloc);
- ;}
- break;
-
- case 235:
-
-/* Line 1455 of yacc.c */
-#line 1411 "glsl_parser.ypp"
- { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;}
- break;
-
- case 240:
-
-/* Line 1455 of yacc.c */
-#line 1419 "glsl_parser.ypp"
- { (yyval.node) = NULL; ;}
- break;
-
- case 241:
-
-/* Line 1455 of yacc.c */
-#line 1420 "glsl_parser.ypp"
- { (yyval.node) = NULL; ;}
- break;
-
- case 244:
-
-/* Line 1455 of yacc.c */
-#line 1427 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.compound_statement) = new(ctx) ast_compound_statement(true, NULL);
- (yyval.compound_statement)->set_location(yylloc);
- ;}
- break;
-
- case 245:
-
-/* Line 1455 of yacc.c */
-#line 1433 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.compound_statement) = new(ctx) ast_compound_statement(true, (yyvsp[(2) - (3)].node));
- (yyval.compound_statement)->set_location(yylloc);
- ;}
- break;
-
- case 246:
-
-/* Line 1455 of yacc.c */
-#line 1441 "glsl_parser.ypp"
- { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;}
- break;
-
- case 248:
-
-/* Line 1455 of yacc.c */
-#line 1447 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.compound_statement) = new(ctx) ast_compound_statement(false, NULL);
- (yyval.compound_statement)->set_location(yylloc);
- ;}
- break;
-
- case 249:
-
-/* Line 1455 of yacc.c */
-#line 1453 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.compound_statement) = new(ctx) ast_compound_statement(false, (yyvsp[(2) - (3)].node));
- (yyval.compound_statement)->set_location(yylloc);
- ;}
- break;
-
- case 250:
-
-/* Line 1455 of yacc.c */
-#line 1462 "glsl_parser.ypp"
- {
- if ((yyvsp[(1) - (1)].node) == NULL) {
- _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "<nil> statement\n");
- assert((yyvsp[(1) - (1)].node) != NULL);
- }
-
- (yyval.node) = (yyvsp[(1) - (1)].node);
- (yyval.node)->link.self_link();
- ;}
- break;
-
- case 251:
-
-/* Line 1455 of yacc.c */
-#line 1472 "glsl_parser.ypp"
- {
- if ((yyvsp[(2) - (2)].node) == NULL) {
- _mesa_glsl_error(& (yylsp[(2) - (2)]), state, "<nil> statement\n");
- assert((yyvsp[(2) - (2)].node) != NULL);
- }
- (yyval.node) = (yyvsp[(1) - (2)].node);
- (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].node)->link);
- ;}
- break;
-
- case 252:
-
-/* Line 1455 of yacc.c */
-#line 1484 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_expression_statement(NULL);
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 253:
-
-/* Line 1455 of yacc.c */
-#line 1490 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_expression_statement((yyvsp[(1) - (2)].expression));
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 254:
-
-/* Line 1455 of yacc.c */
-#line 1499 "glsl_parser.ypp"
- {
- (yyval.node) = new(state) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].selection_rest_statement).then_statement,
- (yyvsp[(5) - (5)].selection_rest_statement).else_statement);
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 255:
-
-/* Line 1455 of yacc.c */
-#line 1508 "glsl_parser.ypp"
- {
- (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (3)].node);
- (yyval.selection_rest_statement).else_statement = (yyvsp[(3) - (3)].node);
- ;}
- break;
-
- case 256:
-
-/* Line 1455 of yacc.c */
-#line 1513 "glsl_parser.ypp"
- {
- (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (1)].node);
- (yyval.selection_rest_statement).else_statement = NULL;
- ;}
- break;
-
- case 257:
-
-/* Line 1455 of yacc.c */
-#line 1521 "glsl_parser.ypp"
- {
- (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression);
- ;}
- break;
-
- case 258:
-
-/* Line 1455 of yacc.c */
-#line 1525 "glsl_parser.ypp"
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression));
- ast_declarator_list *declarator = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type));
- decl->set_location(yylloc);
- declarator->set_location(yylloc);
-
- declarator->declarations.push_tail(&decl->link);
- (yyval.node) = declarator;
- ;}
- break;
-
- case 262:
-
-/* Line 1455 of yacc.c */
-#line 1548 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while,
- NULL, (yyvsp[(3) - (5)].node), NULL, (yyvsp[(5) - (5)].node));
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 263:
-
-/* Line 1455 of yacc.c */
-#line 1555 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while,
- NULL, (yyvsp[(5) - (7)].expression), NULL, (yyvsp[(2) - (7)].node));
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 264:
-
-/* Line 1455 of yacc.c */
-#line 1562 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for,
- (yyvsp[(3) - (6)].node), (yyvsp[(4) - (6)].for_rest_statement).cond, (yyvsp[(4) - (6)].for_rest_statement).rest, (yyvsp[(6) - (6)].node));
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 268:
-
-/* Line 1455 of yacc.c */
-#line 1578 "glsl_parser.ypp"
- {
- (yyval.node) = NULL;
- ;}
- break;
-
- case 269:
-
-/* Line 1455 of yacc.c */
-#line 1585 "glsl_parser.ypp"
- {
- (yyval.for_rest_statement).cond = (yyvsp[(1) - (2)].node);
- (yyval.for_rest_statement).rest = NULL;
- ;}
- break;
-
- case 270:
-
-/* Line 1455 of yacc.c */
-#line 1590 "glsl_parser.ypp"
- {
- (yyval.for_rest_statement).cond = (yyvsp[(1) - (3)].node);
- (yyval.for_rest_statement).rest = (yyvsp[(3) - (3)].expression);
- ;}
- break;
-
- case 271:
-
-/* Line 1455 of yacc.c */
-#line 1599 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL);
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 272:
-
-/* Line 1455 of yacc.c */
-#line 1605 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL);
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 273:
-
-/* Line 1455 of yacc.c */
-#line 1611 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL);
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 274:
-
-/* Line 1455 of yacc.c */
-#line 1617 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, (yyvsp[(2) - (3)].expression));
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 275:
-
-/* Line 1455 of yacc.c */
-#line 1623 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL);
- (yyval.node)->set_location(yylloc);
- ;}
- break;
-
- case 276:
-
-/* Line 1455 of yacc.c */
-#line 1631 "glsl_parser.ypp"
- { (yyval.node) = (yyvsp[(1) - (1)].function_definition); ;}
- break;
-
- case 277:
-
-/* Line 1455 of yacc.c */
-#line 1632 "glsl_parser.ypp"
- { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
- break;
-
- case 278:
-
-/* Line 1455 of yacc.c */
-#line 1633 "glsl_parser.ypp"
- { (yyval.node) = NULL; ;}
- break;
-
- case 279:
-
-/* Line 1455 of yacc.c */
-#line 1638 "glsl_parser.ypp"
- {
- void *ctx = state;
- (yyval.function_definition) = new(ctx) ast_function_definition();
- (yyval.function_definition)->set_location(yylloc);
- (yyval.function_definition)->prototype = (yyvsp[(1) - (2)].function);
- (yyval.function_definition)->body = (yyvsp[(2) - (2)].compound_statement);
- ;}
- break;
-
-
-
-/* Line 1455 of yacc.c */
-#line 5104 "glsl_parser.cpp"
- default: break;
- }
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
- *++yylsp = yyloc;
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if ! YYERROR_VERBOSE
- yyerror (&yylloc, state, YY_("syntax error"));
-#else
- {
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (&yylloc, state, yymsg);
- }
- else
- {
- yyerror (&yylloc, state, YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
- }
-#endif
- }
-
- yyerror_range[0] = yylloc;
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse lookahead token after an
- error, discard it. */
-
- if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
- else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval, &yylloc, state);
- yychar = YYEMPTY;
- }
- }
-
- /* Else will try to reuse lookahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
-
- yyerror_range[0] = yylsp[1-yylen];
- /* Do not reclaim the symbols of the rule which action triggered
- this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
- yyerror_range[0] = *yylsp;
- yydestruct ("Error: popping",
- yystos[yystate], yyvsp, yylsp, state);
- YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- *++yyvsp = yylval;
-
- yyerror_range[1] = yylloc;
- /* Using YYLLOC is tempting, but would change the location of
- the lookahead. YYLOC is available though. */
- YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
- *++yylsp = yyloc;
-
- /* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#if !defined(yyoverflow) || YYERROR_VERBOSE
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
-yyexhaustedlab:
- yyerror (&yylloc, state, YY_("memory exhausted"));
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
- if (yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval, &yylloc, state);
- /* Do not reclaim the symbols of the rule which action triggered
- this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp);
- while (yyssp != yyss)
- {
- yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp, yylsp, state);
- YYPOPSTACK (1);
- }
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
-#endif
- /* Make sure YYID is used. */
- return YYID (yyresult);
-}
-
-
-
+/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 1 + +/* Substitute the variable and function names. */ +#define yyparse _mesa_glsl_parse +#define yylex _mesa_glsl_lex +#define yyerror _mesa_glsl_error +#define yylval _mesa_glsl_lval +#define yychar _mesa_glsl_char +#define yydebug _mesa_glsl_debug +#define yynerrs _mesa_glsl_nerrs +#define yylloc _mesa_glsl_lloc + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "glsl_parser.ypp" + +/* + * Copyright © 2008, 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_types.h" + +#define YYLEX_PARAM state->scanner + + + +/* Line 189 of yacc.c */ +#line 117 "glsl_parser.cpp" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ATTRIBUTE = 258, + CONST_TOK = 259, + BOOL_TOK = 260, + FLOAT_TOK = 261, + INT_TOK = 262, + UINT_TOK = 263, + BREAK = 264, + CONTINUE = 265, + DO = 266, + ELSE = 267, + FOR = 268, + IF = 269, + DISCARD = 270, + RETURN = 271, + SWITCH = 272, + CASE = 273, + DEFAULT = 274, + BVEC2 = 275, + BVEC3 = 276, + BVEC4 = 277, + IVEC2 = 278, + IVEC3 = 279, + IVEC4 = 280, + UVEC2 = 281, + UVEC3 = 282, + UVEC4 = 283, + VEC2 = 284, + VEC3 = 285, + VEC4 = 286, + CENTROID = 287, + IN_TOK = 288, + OUT_TOK = 289, + INOUT_TOK = 290, + UNIFORM = 291, + VARYING = 292, + NOPERSPECTIVE = 293, + FLAT = 294, + SMOOTH = 295, + MAT2X2 = 296, + MAT2X3 = 297, + MAT2X4 = 298, + MAT3X2 = 299, + MAT3X3 = 300, + MAT3X4 = 301, + MAT4X2 = 302, + MAT4X3 = 303, + MAT4X4 = 304, + SAMPLER1D = 305, + SAMPLER2D = 306, + SAMPLER3D = 307, + SAMPLERCUBE = 308, + SAMPLER1DSHADOW = 309, + SAMPLER2DSHADOW = 310, + SAMPLERCUBESHADOW = 311, + SAMPLER1DARRAY = 312, + SAMPLER2DARRAY = 313, + SAMPLER1DARRAYSHADOW = 314, + SAMPLER2DARRAYSHADOW = 315, + ISAMPLER1D = 316, + ISAMPLER2D = 317, + ISAMPLER3D = 318, + ISAMPLERCUBE = 319, + ISAMPLER1DARRAY = 320, + ISAMPLER2DARRAY = 321, + USAMPLER1D = 322, + USAMPLER2D = 323, + USAMPLER3D = 324, + USAMPLERCUBE = 325, + USAMPLER1DARRAY = 326, + USAMPLER2DARRAY = 327, + STRUCT = 328, + VOID_TOK = 329, + WHILE = 330, + IDENTIFIER = 331, + FLOATCONSTANT = 332, + INTCONSTANT = 333, + UINTCONSTANT = 334, + BOOLCONSTANT = 335, + FIELD_SELECTION = 336, + LEFT_OP = 337, + RIGHT_OP = 338, + INC_OP = 339, + DEC_OP = 340, + LE_OP = 341, + GE_OP = 342, + EQ_OP = 343, + NE_OP = 344, + AND_OP = 345, + OR_OP = 346, + XOR_OP = 347, + MUL_ASSIGN = 348, + DIV_ASSIGN = 349, + ADD_ASSIGN = 350, + MOD_ASSIGN = 351, + LEFT_ASSIGN = 352, + RIGHT_ASSIGN = 353, + AND_ASSIGN = 354, + XOR_ASSIGN = 355, + OR_ASSIGN = 356, + SUB_ASSIGN = 357, + INVARIANT = 358, + LOWP = 359, + MEDIUMP = 360, + HIGHP = 361, + SUPERP = 362, + PRECISION = 363, + VERSION = 364, + EXTENSION = 365, + LINE = 366, + COLON = 367, + EOL = 368, + INTERFACE = 369, + OUTPUT = 370, + PRAGMA_DEBUG_ON = 371, + PRAGMA_DEBUG_OFF = 372, + PRAGMA_OPTIMIZE_ON = 373, + PRAGMA_OPTIMIZE_OFF = 374, + PRAGMA_INVARIANT_ALL = 375, + LAYOUT_TOK = 376, + ASM = 377, + CLASS = 378, + UNION = 379, + ENUM = 380, + TYPEDEF = 381, + TEMPLATE = 382, + THIS = 383, + PACKED_TOK = 384, + GOTO = 385, + INLINE_TOK = 386, + NOINLINE = 387, + VOLATILE = 388, + PUBLIC_TOK = 389, + STATIC = 390, + EXTERN = 391, + EXTERNAL = 392, + LONG_TOK = 393, + SHORT_TOK = 394, + DOUBLE_TOK = 395, + HALF = 396, + FIXED_TOK = 397, + UNSIGNED = 398, + INPUT_TOK = 399, + OUPTUT = 400, + HVEC2 = 401, + HVEC3 = 402, + HVEC4 = 403, + DVEC2 = 404, + DVEC3 = 405, + DVEC4 = 406, + FVEC2 = 407, + FVEC3 = 408, + FVEC4 = 409, + SAMPLER2DRECT = 410, + SAMPLER3DRECT = 411, + SAMPLER2DRECTSHADOW = 412, + SIZEOF = 413, + CAST = 414, + NAMESPACE = 415, + USING = 416, + ERROR_TOK = 417, + COMMON = 418, + PARTITION = 419, + ACTIVE = 420, + SAMPLERBUFFER = 421, + FILTER = 422, + IMAGE1D = 423, + IMAGE2D = 424, + IMAGE3D = 425, + IMAGECUBE = 426, + IMAGE1DARRAY = 427, + IMAGE2DARRAY = 428, + IIMAGE1D = 429, + IIMAGE2D = 430, + IIMAGE3D = 431, + IIMAGECUBE = 432, + IIMAGE1DARRAY = 433, + IIMAGE2DARRAY = 434, + UIMAGE1D = 435, + UIMAGE2D = 436, + UIMAGE3D = 437, + UIMAGECUBE = 438, + UIMAGE1DARRAY = 439, + UIMAGE2DARRAY = 440, + IMAGE1DSHADOW = 441, + IMAGE2DSHADOW = 442, + IMAGEBUFFER = 443, + IIMAGEBUFFER = 444, + UIMAGEBUFFER = 445, + IMAGE1DARRAYSHADOW = 446, + IMAGE2DARRAYSHADOW = 447, + ROW_MAJOR = 448 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 214 of yacc.c */ +#line 52 "glsl_parser.ypp" + + int n; + float real; + char *identifier; + + struct ast_type_qualifier type_qualifier; + + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; + + struct { + ast_node *cond; + ast_expression *rest; + } for_rest_statement; + + struct { + ast_node *then_statement; + ast_node *else_statement; + } selection_rest_statement; + + + +/* Line 214 of yacc.c */ +#line 378 "glsl_parser.cpp" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 403 "glsl_parser.cpp" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 5 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 3738 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 218 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 87 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 279 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 415 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 448 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 202, 2, 2, 2, 206, 209, 2, + 194, 195, 204, 200, 199, 201, 198, 205, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 213, 215, + 207, 214, 208, 212, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 196, 2, 197, 210, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 216, 211, 217, 203, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 4, 9, 10, 14, 17, 20, 23, + 26, 29, 30, 33, 39, 41, 44, 46, 48, 50, + 52, 54, 56, 60, 62, 67, 69, 73, 76, 79, + 81, 83, 85, 89, 92, 95, 98, 100, 103, 107, + 110, 112, 114, 116, 118, 121, 124, 127, 129, 131, + 133, 135, 137, 141, 145, 149, 151, 155, 159, 161, + 165, 169, 171, 175, 179, 183, 187, 189, 193, 197, + 199, 203, 205, 209, 211, 215, 217, 221, 223, 227, + 229, 233, 235, 241, 243, 247, 249, 251, 253, 255, + 257, 259, 261, 263, 265, 267, 269, 271, 275, 277, + 280, 283, 288, 291, 293, 295, 298, 302, 306, 309, + 315, 319, 322, 326, 329, 330, 332, 334, 336, 338, + 340, 344, 350, 357, 365, 374, 380, 382, 385, 390, + 396, 403, 411, 416, 419, 421, 424, 429, 431, 435, + 437, 441, 443, 445, 447, 449, 451, 453, 456, 458, + 461, 464, 468, 470, 472, 474, 476, 479, 481, 483, + 486, 489, 491, 493, 496, 498, 502, 507, 509, 511, + 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, + 533, 535, 537, 539, 541, 543, 545, 547, 549, 551, + 553, 555, 557, 559, 561, 563, 565, 567, 569, 571, + 573, 575, 577, 579, 581, 583, 585, 587, 589, 591, + 593, 595, 597, 599, 601, 603, 605, 607, 609, 611, + 613, 615, 617, 619, 621, 627, 632, 634, 637, 641, + 643, 647, 649, 654, 656, 658, 660, 662, 664, 666, + 668, 670, 672, 674, 676, 679, 683, 685, 687, 690, + 694, 696, 699, 701, 704, 710, 714, 716, 718, 723, + 729, 733, 736, 742, 750, 757, 759, 761, 763, 764, + 767, 771, 774, 777, 780, 784, 787, 789, 791, 793 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int16 yyrhs[] = +{ + 219, 0, -1, -1, 221, 223, 220, 225, -1, -1, + 109, 78, 113, -1, 116, 113, -1, 117, 113, -1, + 118, 113, -1, 119, 113, -1, 120, 113, -1, -1, + 223, 224, -1, 110, 76, 112, 76, 113, -1, 303, + -1, 225, 303, -1, 76, -1, 226, -1, 78, -1, + 79, -1, 77, -1, 80, -1, 194, 253, 195, -1, + 227, -1, 228, 196, 229, 197, -1, 230, -1, 228, + 198, 76, -1, 228, 84, -1, 228, 85, -1, 253, + -1, 231, -1, 232, -1, 228, 198, 232, -1, 234, + 195, -1, 233, 195, -1, 235, 74, -1, 235, -1, + 235, 251, -1, 234, 199, 251, -1, 236, 194, -1, + 274, -1, 76, -1, 81, -1, 228, -1, 84, 237, + -1, 85, 237, -1, 238, 237, -1, 200, -1, 201, + -1, 202, -1, 203, -1, 237, -1, 239, 204, 237, + -1, 239, 205, 237, -1, 239, 206, 237, -1, 239, + -1, 240, 200, 239, -1, 240, 201, 239, -1, 240, + -1, 241, 82, 240, -1, 241, 83, 240, -1, 241, + -1, 242, 207, 241, -1, 242, 208, 241, -1, 242, + 86, 241, -1, 242, 87, 241, -1, 242, -1, 243, + 88, 242, -1, 243, 89, 242, -1, 243, -1, 244, + 209, 243, -1, 244, -1, 245, 210, 244, -1, 245, + -1, 246, 211, 245, -1, 246, -1, 247, 90, 246, + -1, 247, -1, 248, 92, 247, -1, 248, -1, 249, + 91, 248, -1, 249, -1, 249, 212, 253, 213, 251, + -1, 250, -1, 237, 252, 251, -1, 214, -1, 93, + -1, 94, -1, 96, -1, 95, -1, 102, -1, 97, + -1, 98, -1, 99, -1, 100, -1, 101, -1, 251, + -1, 253, 199, 251, -1, 250, -1, 256, 215, -1, + 264, 215, -1, 108, 278, 275, 215, -1, 257, 195, + -1, 259, -1, 258, -1, 259, 261, -1, 258, 199, + 261, -1, 266, 76, 194, -1, 274, 76, -1, 274, + 76, 196, 254, 197, -1, 271, 262, 260, -1, 262, + 260, -1, 271, 262, 263, -1, 262, 263, -1, -1, + 33, -1, 34, -1, 35, -1, 274, -1, 265, -1, + 264, 199, 76, -1, 264, 199, 76, 196, 197, -1, + 264, 199, 76, 196, 254, 197, -1, 264, 199, 76, + 196, 197, 214, 284, -1, 264, 199, 76, 196, 254, + 197, 214, 284, -1, 264, 199, 76, 214, 284, -1, + 266, -1, 266, 76, -1, 266, 76, 196, 197, -1, + 266, 76, 196, 254, 197, -1, 266, 76, 196, 197, + 214, 284, -1, 266, 76, 196, 254, 197, 214, 284, + -1, 266, 76, 214, 284, -1, 103, 76, -1, 274, + -1, 272, 274, -1, 121, 194, 268, 195, -1, 269, + -1, 268, 199, 269, -1, 76, -1, 76, 214, 78, + -1, 40, -1, 39, -1, 38, -1, 4, -1, 273, + -1, 267, -1, 267, 273, -1, 270, -1, 270, 273, + -1, 103, 273, -1, 103, 270, 273, -1, 103, -1, + 4, -1, 3, -1, 37, -1, 32, 37, -1, 33, + -1, 34, -1, 32, 33, -1, 32, 34, -1, 36, + -1, 275, -1, 278, 275, -1, 276, -1, 276, 196, + 197, -1, 276, 196, 254, 197, -1, 277, -1, 279, + -1, 76, -1, 74, -1, 6, -1, 7, -1, 8, + -1, 5, -1, 29, -1, 30, -1, 31, -1, 20, + -1, 21, -1, 22, -1, 23, -1, 24, -1, 25, + -1, 26, -1, 27, -1, 28, -1, 41, -1, 42, + -1, 43, -1, 44, -1, 45, -1, 46, -1, 47, + -1, 48, -1, 49, -1, 50, -1, 51, -1, 155, + -1, 52, -1, 53, -1, 54, -1, 55, -1, 157, + -1, 56, -1, 57, -1, 58, -1, 59, -1, 60, + -1, 61, -1, 62, -1, 63, -1, 64, -1, 65, + -1, 66, -1, 67, -1, 68, -1, 69, -1, 70, + -1, 71, -1, 72, -1, 106, -1, 105, -1, 104, + -1, 73, 76, 216, 280, 217, -1, 73, 216, 280, + 217, -1, 281, -1, 280, 281, -1, 274, 282, 215, + -1, 283, -1, 282, 199, 283, -1, 76, -1, 76, + 196, 254, 197, -1, 251, -1, 255, -1, 288, -1, + 287, -1, 285, -1, 292, -1, 293, -1, 296, -1, + 297, -1, 298, -1, 302, -1, 216, 217, -1, 216, + 291, 217, -1, 290, -1, 287, -1, 216, 217, -1, + 216, 291, 217, -1, 286, -1, 291, 286, -1, 215, + -1, 253, 215, -1, 14, 194, 253, 195, 294, -1, + 286, 12, 286, -1, 286, -1, 253, -1, 266, 76, + 214, 284, -1, 17, 194, 253, 195, 288, -1, 18, + 253, 213, -1, 19, 213, -1, 75, 194, 295, 195, + 289, -1, 11, 286, 75, 194, 253, 195, 215, -1, + 13, 194, 299, 301, 195, 289, -1, 292, -1, 285, + -1, 295, -1, -1, 300, 215, -1, 300, 215, 253, + -1, 10, 215, -1, 9, 215, -1, 16, 215, -1, + 16, 253, 215, -1, 15, 215, -1, 304, -1, 255, + -1, 222, -1, 256, 290, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 213, 213, 212, 219, 221, 246, 247, 248, 249, + 250, 262, 264, 268, 277, 285, 296, 300, 307, 314, + 321, 328, 335, 342, 343, 349, 353, 360, 366, 375, + 379, 383, 384, 393, 394, 398, 399, 403, 409, 421, + 425, 431, 438, 449, 450, 456, 462, 472, 473, 474, + 475, 479, 480, 486, 492, 501, 502, 508, 517, 518, + 524, 533, 534, 540, 546, 552, 561, 562, 568, 577, + 578, 587, 588, 597, 598, 607, 608, 617, 618, 627, + 628, 637, 638, 647, 648, 657, 658, 659, 660, 661, + 662, 663, 664, 665, 666, 667, 671, 675, 691, 695, + 699, 703, 712, 716, 717, 721, 726, 734, 745, 755, + 770, 777, 782, 793, 806, 809, 814, 819, 828, 832, + 833, 842, 851, 860, 869, 878, 891, 902, 911, 920, + 929, 938, 947, 956, 970, 977, 988, 995, 996, 1015, + 1044, 1085, 1090, 1095, 1103, 1111, 1112, 1113, 1118, 1119, + 1124, 1129, 1135, 1143, 1148, 1153, 1158, 1164, 1169, 1174, + 1179, 1184, 1192, 1196, 1204, 1205, 1211, 1220, 1226, 1232, + 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, + 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, + 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, + 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, + 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, + 1291, 1295, 1305, 1315, 1328, 1334, 1343, 1348, 1356, 1371, + 1376, 1384, 1390, 1399, 1403, 1409, 1410, 1414, 1415, 1416, + 1417, 1418, 1419, 1420, 1424, 1430, 1439, 1440, 1444, 1450, + 1459, 1469, 1481, 1487, 1496, 1505, 1510, 1518, 1522, 1536, + 1540, 1541, 1545, 1552, 1559, 1569, 1570, 1574, 1576, 1582, + 1587, 1596, 1602, 1608, 1614, 1620, 1629, 1630, 1631, 1635 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ATTRIBUTE", "CONST_TOK", "BOOL_TOK", + "FLOAT_TOK", "INT_TOK", "UINT_TOK", "BREAK", "CONTINUE", "DO", "ELSE", + "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "BVEC2", + "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "UVEC2", "UVEC3", "UVEC4", + "VEC2", "VEC3", "VEC4", "CENTROID", "IN_TOK", "OUT_TOK", "INOUT_TOK", + "UNIFORM", "VARYING", "NOPERSPECTIVE", "FLAT", "SMOOTH", "MAT2X2", + "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", + "MAT4X4", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", + "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", + "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", + "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", + "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D", + "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY", + "USAMPLER2DARRAY", "STRUCT", "VOID_TOK", "WHILE", "IDENTIFIER", + "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", + "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", + "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", + "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", + "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "INVARIANT", + "LOWP", "MEDIUMP", "HIGHP", "SUPERP", "PRECISION", "VERSION", + "EXTENSION", "LINE", "COLON", "EOL", "INTERFACE", "OUTPUT", + "PRAGMA_DEBUG_ON", "PRAGMA_DEBUG_OFF", "PRAGMA_OPTIMIZE_ON", + "PRAGMA_OPTIMIZE_OFF", "PRAGMA_INVARIANT_ALL", "LAYOUT_TOK", "ASM", + "CLASS", "UNION", "ENUM", "TYPEDEF", "TEMPLATE", "THIS", "PACKED_TOK", + "GOTO", "INLINE_TOK", "NOINLINE", "VOLATILE", "PUBLIC_TOK", "STATIC", + "EXTERN", "EXTERNAL", "LONG_TOK", "SHORT_TOK", "DOUBLE_TOK", "HALF", + "FIXED_TOK", "UNSIGNED", "INPUT_TOK", "OUPTUT", "HVEC2", "HVEC3", + "HVEC4", "DVEC2", "DVEC3", "DVEC4", "FVEC2", "FVEC3", "FVEC4", + "SAMPLER2DRECT", "SAMPLER3DRECT", "SAMPLER2DRECTSHADOW", "SIZEOF", + "CAST", "NAMESPACE", "USING", "ERROR_TOK", "COMMON", "PARTITION", + "ACTIVE", "SAMPLERBUFFER", "FILTER", "IMAGE1D", "IMAGE2D", "IMAGE3D", + "IMAGECUBE", "IMAGE1DARRAY", "IMAGE2DARRAY", "IIMAGE1D", "IIMAGE2D", + "IIMAGE3D", "IIMAGECUBE", "IIMAGE1DARRAY", "IIMAGE2DARRAY", "UIMAGE1D", + "UIMAGE2D", "UIMAGE3D", "UIMAGECUBE", "UIMAGE1DARRAY", "UIMAGE2DARRAY", + "IMAGE1DSHADOW", "IMAGE2DSHADOW", "IMAGEBUFFER", "IIMAGEBUFFER", + "UIMAGEBUFFER", "IMAGE1DARRAYSHADOW", "IMAGE2DARRAYSHADOW", "ROW_MAJOR", + "'('", "')'", "'['", "']'", "'.'", "','", "'+'", "'-'", "'!'", "'~'", + "'*'", "'/'", "'%'", "'<'", "'>'", "'&'", "'^'", "'|'", "'?'", "':'", + "'='", "';'", "'{'", "'}'", "$accept", "translation_unit", "$@1", + "version_statement", "pragma_statement", "extension_statement_list", + "extension_statement", "external_declaration_list", + "variable_identifier", "primary_expression", "postfix_expression", + "integer_expression", "function_call", "function_call_or_method", + "function_call_generic", "function_call_header_no_parameters", + "function_call_header_with_parameters", "function_call_header", + "function_identifier", "unary_expression", "unary_operator", + "multiplicative_expression", "additive_expression", "shift_expression", + "relational_expression", "equality_expression", "and_expression", + "exclusive_or_expression", "inclusive_or_expression", + "logical_and_expression", "logical_xor_expression", + "logical_or_expression", "conditional_expression", + "assignment_expression", "assignment_operator", "expression", + "constant_expression", "declaration", "function_prototype", + "function_declarator", "function_header_with_parameters", + "function_header", "parameter_declarator", "parameter_declaration", + "parameter_qualifier", "parameter_type_specifier", + "init_declarator_list", "single_declaration", "fully_specified_type", + "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", + "interpolation_qualifier", "parameter_type_qualifier", "type_qualifier", + "storage_qualifier", "type_specifier", "type_specifier_no_prec", + "type_specifier_nonarray", "basic_type_specifier_nonarray", + "precision_qualifier", "struct_specifier", "struct_declaration_list", + "struct_declaration", "struct_declarator_list", "struct_declarator", + "initializer", "declaration_statement", "statement", "simple_statement", + "compound_statement", "statement_no_new_scope", + "compound_statement_no_new_scope", "statement_list", + "expression_statement", "selection_statement", + "selection_rest_statement", "condition", "switch_statement", + "case_label", "iteration_statement", "for_init_statement", + "conditionopt", "for_rest_statement", "jump_statement", + "external_declaration", "function_definition", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 40, 41, 91, 93, 46, 44, + 43, 45, 33, 126, 42, 47, 37, 60, 62, 38, + 94, 124, 63, 58, 61, 59, 123, 125 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 218, 220, 219, 221, 221, 222, 222, 222, 222, + 222, 223, 223, 224, 225, 225, 226, 227, 227, 227, + 227, 227, 227, 228, 228, 228, 228, 228, 228, 229, + 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, + 236, 236, 236, 237, 237, 237, 237, 238, 238, 238, + 238, 239, 239, 239, 239, 240, 240, 240, 241, 241, + 241, 242, 242, 242, 242, 242, 243, 243, 243, 244, + 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, + 249, 250, 250, 251, 251, 252, 252, 252, 252, 252, + 252, 252, 252, 252, 252, 252, 253, 253, 254, 255, + 255, 255, 256, 257, 257, 258, 258, 259, 260, 260, + 261, 261, 261, 261, 262, 262, 262, 262, 263, 264, + 264, 264, 264, 264, 264, 264, 265, 265, 265, 265, + 265, 265, 265, 265, 266, 266, 267, 268, 268, 269, + 269, 270, 270, 270, 271, 272, 272, 272, 272, 272, + 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 274, 274, 275, 275, 275, 276, 276, 276, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 278, 278, 278, 279, 279, 280, 280, 281, 282, + 282, 283, 283, 284, 285, 286, 286, 287, 287, 287, + 287, 287, 287, 287, 288, 288, 289, 289, 290, 290, + 291, 291, 292, 292, 293, 294, 294, 295, 295, 296, + 297, 297, 298, 298, 298, 299, 299, 300, 300, 301, + 301, 302, 302, 302, 302, 302, 303, 303, 303, 304 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 4, 0, 3, 2, 2, 2, 2, + 2, 0, 2, 5, 1, 2, 1, 1, 1, 1, + 1, 1, 3, 1, 4, 1, 3, 2, 2, 1, + 1, 1, 3, 2, 2, 2, 1, 2, 3, 2, + 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, + 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 5, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, + 2, 4, 2, 1, 1, 2, 3, 3, 2, 5, + 3, 2, 3, 2, 0, 1, 1, 1, 1, 1, + 3, 5, 6, 7, 8, 5, 1, 2, 4, 5, + 6, 7, 4, 2, 1, 2, 4, 1, 3, 1, + 3, 1, 1, 1, 1, 1, 1, 2, 1, 2, + 2, 3, 1, 1, 1, 1, 2, 1, 1, 2, + 2, 1, 1, 2, 1, 3, 4, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 5, 4, 1, 2, 3, 1, + 3, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 3, 1, 1, 2, 3, + 1, 2, 1, 2, 5, 3, 1, 1, 4, 5, + 3, 2, 5, 7, 6, 1, 1, 1, 0, 2, + 3, 2, 2, 2, 3, 2, 1, 1, 1, 2 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 4, 0, 0, 11, 0, 1, 2, 5, 0, 0, + 12, 0, 154, 153, 174, 171, 172, 173, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 175, 176, 177, + 0, 157, 158, 161, 155, 143, 142, 141, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 199, + 200, 201, 202, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 0, 170, 169, 152, 223, 222, 221, 0, 0, 0, + 0, 0, 0, 0, 198, 203, 278, 3, 277, 0, + 0, 104, 114, 0, 119, 126, 146, 148, 0, 145, + 134, 162, 164, 167, 0, 168, 14, 276, 0, 159, + 160, 156, 0, 0, 133, 0, 150, 0, 6, 7, + 8, 9, 10, 0, 15, 99, 0, 279, 102, 114, + 144, 115, 116, 117, 105, 0, 114, 0, 100, 127, + 147, 149, 135, 0, 163, 0, 0, 0, 0, 226, + 151, 0, 139, 0, 137, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 20, 18, 19, + 21, 42, 0, 0, 0, 47, 48, 49, 50, 252, + 0, 248, 17, 23, 43, 25, 30, 31, 0, 0, + 36, 0, 51, 0, 55, 58, 61, 66, 69, 71, + 73, 75, 77, 79, 81, 83, 96, 0, 234, 0, + 134, 237, 250, 236, 235, 0, 238, 239, 240, 241, + 242, 243, 106, 111, 113, 118, 0, 120, 107, 0, + 0, 165, 51, 98, 0, 40, 13, 0, 231, 0, + 229, 225, 227, 101, 0, 136, 0, 272, 271, 0, + 0, 0, 275, 273, 0, 0, 0, 261, 0, 44, + 45, 0, 244, 0, 27, 28, 0, 0, 34, 33, + 0, 170, 37, 39, 86, 87, 89, 88, 91, 92, + 93, 94, 95, 90, 85, 0, 46, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 253, 249, + 251, 108, 110, 112, 0, 0, 128, 0, 233, 132, + 166, 224, 0, 0, 228, 140, 138, 0, 266, 265, + 268, 0, 274, 0, 260, 152, 257, 0, 0, 22, + 245, 0, 29, 26, 32, 38, 84, 52, 53, 54, + 56, 57, 59, 60, 64, 65, 62, 63, 67, 68, + 70, 72, 74, 76, 78, 80, 0, 97, 0, 121, + 0, 125, 0, 129, 0, 230, 0, 267, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 0, 122, 130, + 0, 232, 0, 269, 0, 256, 254, 259, 0, 247, + 262, 246, 82, 109, 123, 0, 131, 0, 270, 264, + 0, 258, 124, 263, 255 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 2, 9, 3, 86, 6, 10, 87, 182, 183, + 184, 341, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 285, 207, 234, 208, 209, 90, + 91, 92, 223, 134, 135, 224, 93, 94, 95, 96, + 153, 154, 97, 136, 98, 99, 235, 101, 102, 103, + 104, 105, 148, 149, 239, 240, 319, 211, 212, 213, + 214, 400, 401, 215, 216, 217, 396, 338, 218, 219, + 220, 330, 378, 379, 221, 106, 107 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -321 +static const yytype_int16 yypact[] = +{ + -86, -57, 45, -321, -56, -321, -50, -321, -10, 3320, + -321, -26, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + 79, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -70, -321, -321, 43, -321, -321, -321, 18, -22, -12, + -5, 2, 25, -101, -321, -321, -321, 3320, -321, -43, + -55, -54, 6, -148, -321, 52, 211, 211, 3509, -321, + -321, -321, -47, -321, 3581, -321, -321, -321, 110, -321, + -321, -321, -14, 3509, -321, 211, -321, 3581, -321, -321, + -321, -321, -321, 131, -321, -321, 389, -321, -321, 15, + -321, -321, -321, -321, -321, 3509, 109, 136, -321, -152, + -321, -321, -321, 2400, -321, 105, 3509, 143, 1781, -321, + -321, 7, 9, -107, -321, 10, 12, 1249, 27, 36, + 17, 2015, 40, 2952, 22, 42, -65, -321, -321, -321, + -321, -321, 2952, 2952, 2952, -321, -321, -321, -321, -321, + 604, -321, -321, -321, -20, -321, -321, -321, 47, -92, + 3136, 46, -67, 2952, -24, -16, 111, -73, 108, 37, + 41, 39, 162, 161, -82, -321, -321, -147, -321, 44, + 61, -321, -321, -321, -321, 819, -321, -321, -321, -321, + -321, -321, -321, -321, -321, 181, 3509, -160, -321, 2584, + 2952, -321, -321, -321, 63, -321, -321, 1898, 62, -146, + -321, -321, -321, -321, 183, -321, 131, -321, -321, 187, + 1664, 2952, -321, -321, -144, 2952, -140, -321, 2216, -321, + -321, -81, -321, 1034, -321, -321, 2952, 3437, -321, -321, + 2952, 70, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, -321, -321, -321, 2952, -321, 2952, 2952, 2952, + 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, + 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, -321, -321, + -321, 74, -321, -321, 2768, 2952, 64, 69, -321, -321, + -321, -321, 2952, 143, -321, -321, -321, 82, -321, -321, + 2216, -74, -321, -68, -321, 235, 78, 203, 85, -321, + -321, 84, 78, 88, -321, -321, -321, -321, -321, -321, + -24, -24, -16, -16, 111, 111, 111, 111, -73, -73, + 108, 37, 41, 39, 162, 161, -129, -321, 2952, 71, + 86, -321, 2952, 72, 87, -321, 2952, -321, 73, 92, + 1249, 75, 76, 1463, -321, 2952, 95, 2952, 80, -321, + 2952, -321, -63, 2952, 1463, 277, -321, -321, 2952, -321, + -321, -321, -321, -321, -321, 2952, -321, 81, 78, -321, + 1249, -321, -321, -321, -321 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, -321, -321, 26, -321, -321, -321, -321, -135, + -321, -91, -88, -106, -90, -3, -6, -4, -2, -1, + 0, -321, -139, -174, -321, -156, -217, 11, 13, -321, + -321, -321, 83, 170, 164, 89, -321, -321, -243, -321, + -321, 56, -71, -321, -321, -72, -9, -32, -321, -321, + 227, -321, 160, -131, -321, -15, -195, 57, -154, -320, + -69, -84, 222, 133, 66, -321, -321, -13, -321, -321, + -321, -321, -321, -321, -321, 231, -321 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -170 +static const yytype_int16 yytable[] = +{ + 100, 116, 115, 249, 233, 254, 112, 256, 232, 305, + 130, -169, 317, 294, 295, 337, 272, 242, 261, 130, + 88, 4, 89, 1, 140, 141, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 314, 259, 260, 131, + 132, 133, 228, 150, 229, 5, 12, 13, 131, 132, + 133, 137, 307, 323, 315, 307, 318, 7, 286, 307, + 8, 310, 230, 399, 264, 265, 11, 138, 308, 324, + 307, 332, 144, 334, 399, 30, 31, 32, 100, 33, + 34, 35, 36, 37, 385, 151, 108, 337, 245, 142, + 233, 118, 246, 123, 232, 331, 345, 370, 88, 333, + 89, 119, 336, 269, 147, 374, 242, 270, 120, 310, + 342, 346, 109, 110, 339, 121, 111, 210, 307, 114, + 371, 380, 74, 75, 76, 307, 225, 381, 139, -41, + 306, 307, 407, 367, 296, 297, 307, 147, 122, 147, + 128, 318, 131, 132, 133, 129, 113, 284, 210, 143, + 366, 386, 347, 348, 349, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 210, 125, 126, 336, 233, 266, 389, 267, 232, + 287, 288, 289, 233, 290, 291, 145, 232, 354, 355, + 356, 357, 404, 292, 293, 406, 298, 299, 318, 350, + 351, -103, 146, 411, 352, 353, 210, 152, 358, 359, + 412, 402, 227, 318, 12, 13, 318, 225, 236, 238, + 392, 250, 243, 244, 318, 247, 395, 248, 147, 233, + 251, 318, 252, 232, 255, 257, 258, 408, 12, 13, + 273, 210, 268, 30, 31, 32, 300, 33, 34, 210, + 302, 301, 303, 304, 210, -40, 414, 311, 322, 125, + 320, 325, 327, 116, 115, -35, 373, 30, 31, 32, + 368, 33, 34, 35, 36, 37, 376, 307, 372, 382, + 383, 384, -41, 388, 391, 387, 390, 394, 393, 410, + 398, 180, 403, 344, 405, 361, 413, 360, 362, 222, + 226, 363, 326, 364, 117, 365, 237, 328, 375, 312, + 409, 127, 397, 263, 0, 313, 329, 377, 124, 0, + 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 210, 0, 0, 210, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, + 0, 0, 12, 13, 14, 15, 16, 17, 155, 156, + 157, 210, 158, 159, 160, 161, 162, 163, 164, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 0, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 165, 166, 167, 168, 169, 170, + 171, 0, 0, 172, 173, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 73, 74, 75, 76, 0, 77, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 174, 0, 0, 0, 0, 0, 175, + 176, 177, 178, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 179, 180, 181, 12, 13, 14, + 15, 16, 17, 155, 156, 157, 0, 158, 159, 160, + 161, 162, 163, 164, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 165, + 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, + 76, 0, 77, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, + 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 174, 0, + 0, 0, 0, 0, 175, 176, 177, 178, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, + 180, 262, 12, 13, 14, 15, 16, 17, 155, 156, + 157, 0, 158, 159, 160, 161, 162, 163, 164, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 0, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 165, 166, 167, 168, 169, 170, + 171, 0, 0, 172, 173, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 73, 74, 75, 76, 0, 77, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 174, 0, 0, 0, 0, 0, 175, + 176, 177, 178, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 179, 180, 309, 12, 13, 14, + 15, 16, 17, 155, 156, 157, 0, 158, 159, 160, + 161, 162, 163, 164, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 165, + 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, + 76, 0, 77, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, + 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 174, 0, + 0, 0, 0, 0, 175, 176, 177, 178, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, + 180, 340, 12, 13, 14, 15, 16, 17, 155, 156, + 157, 0, 158, 159, 160, 161, 162, 163, 164, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 0, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 165, 166, 167, 168, 169, 170, + 171, 0, 0, 172, 173, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 73, 74, 75, 76, 0, 77, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 174, 0, 0, 0, 0, 0, 175, + 176, 177, 178, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 179, 180, 12, 13, 14, 15, + 16, 17, 155, 156, 157, 0, 158, 159, 160, 161, + 162, 163, 164, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 0, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 165, 166, + 167, 168, 169, 170, 171, 0, 0, 172, 173, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 73, 74, 75, 76, + 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, + 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, + 0, 0, 0, 175, 176, 177, 178, 12, 13, 14, + 15, 16, 17, 0, 0, 0, 0, 0, 179, 126, + 0, 0, 0, 0, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 0, + 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, + 76, 0, 77, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 83, 14, 15, 16, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 0, 0, 0, 0, 0, 0, 84, + 0, 85, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 0, 72, 174, 0, + 0, 0, 0, 0, 175, 176, 177, 178, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, + 0, 0, 0, 0, 0, 74, 75, 76, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 0, 0, 0, 0, 0, 0, 84, 0, 85, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 0, 72, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, + 0, 0, 74, 75, 76, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, + 0, 0, 0, 84, 0, 85, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 0, 166, 167, 168, 169, 170, 171, 0, 0, 172, + 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 0, 0, 0, 74, + 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 84, 0, 85, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, + 0, 0, 0, 0, 0, 175, 176, 177, 178, 12, + 13, 14, 15, 16, 17, 0, 0, 0, 0, 0, + 253, 0, 0, 0, 0, 0, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 0, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 0, 166, 167, 168, 169, 170, 171, 0, 0, + 172, 173, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, + 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 0, 85, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 14, 15, 16, 17, 0, + 174, 0, 0, 0, 0, 0, 175, 176, 177, 178, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 0, 166, 167, 168, 169, + 170, 171, 0, 0, 172, 173, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 74, 75, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 0, 85, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 15, 16, 17, 0, 174, 0, 0, 231, 0, 0, + 175, 176, 177, 178, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 0, + 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, + 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, + 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 15, 16, 17, 0, 174, 0, + 0, 316, 0, 0, 175, 176, 177, 178, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 0, 166, 167, 168, 169, 170, 171, + 0, 0, 172, 173, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 74, 75, 76, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 84, 0, 85, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 15, 16, + 17, 0, 174, 0, 0, 369, 0, 0, 175, 176, + 177, 178, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 0, 166, 167, + 168, 169, 170, 171, 0, 0, 172, 173, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 74, 75, 76, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 84, 0, 85, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 14, 15, 16, 17, 0, 174, 0, 0, 0, + 0, 0, 175, 176, 177, 178, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 271, 0, 166, 167, 168, 169, 170, 171, 0, 0, + 172, 173, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 0, 85, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 13, 14, 15, 16, 17, 0, + 174, 0, 0, 0, 0, 0, 175, 176, 177, 178, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 0, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 0, 72, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 73, 74, 75, 76, 0, 77, 0, + 0, 0, 0, 0, 0, 0, 78, 79, 80, 81, + 82, 83, 14, 15, 16, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, + 0, 0, 0, 0, 0, 84, 0, 85, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 0, 343, 14, 15, 16, 17, 171, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 74, 75, 76, 0, 0, 0, 0, 0, 0, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 0, 72, 14, 15, 16, 17, + 0, 0, 84, 0, 85, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 74, 75, 76, 0, 0, 0, 0, + 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 0, 72, 0, 0, + 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 84, 0, 85 +}; + +static const yytype_int16 yycheck[] = +{ + 9, 73, 73, 157, 143, 161, 76, 163, 143, 91, + 4, 76, 229, 86, 87, 258, 190, 148, 174, 4, + 9, 78, 9, 109, 96, 97, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 196, 172, 173, 33, + 34, 35, 194, 115, 196, 0, 3, 4, 33, 34, + 35, 199, 199, 199, 214, 199, 230, 113, 193, 199, + 110, 215, 214, 383, 84, 85, 76, 215, 215, 215, + 199, 215, 104, 213, 394, 32, 33, 34, 87, 36, + 37, 38, 39, 40, 213, 117, 112, 330, 195, 98, + 229, 113, 199, 194, 229, 251, 270, 314, 87, 255, + 87, 113, 258, 195, 113, 322, 237, 199, 113, 263, + 266, 285, 33, 34, 195, 113, 37, 126, 199, 76, + 315, 195, 104, 105, 106, 199, 135, 195, 76, 194, + 212, 199, 195, 307, 207, 208, 199, 146, 113, 148, + 195, 315, 33, 34, 35, 199, 216, 214, 157, 196, + 306, 368, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 180, 215, 216, 330, 314, 196, 372, 198, 314, + 204, 205, 206, 322, 200, 201, 76, 322, 294, 295, + 296, 297, 387, 82, 83, 390, 88, 89, 372, 290, + 291, 195, 216, 398, 292, 293, 215, 76, 298, 299, + 405, 385, 76, 387, 3, 4, 390, 226, 113, 76, + 376, 194, 215, 214, 398, 215, 380, 215, 237, 368, + 194, 405, 215, 368, 194, 213, 194, 393, 3, 4, + 194, 250, 195, 32, 33, 34, 209, 36, 37, 258, + 211, 210, 90, 92, 263, 194, 410, 76, 196, 215, + 197, 78, 75, 335, 335, 195, 197, 32, 33, 34, + 196, 36, 37, 38, 39, 40, 194, 199, 214, 76, + 195, 197, 194, 197, 197, 214, 214, 195, 215, 12, + 214, 216, 197, 267, 214, 301, 215, 300, 302, 129, + 136, 303, 246, 304, 77, 305, 146, 250, 323, 226, + 394, 89, 381, 180, -1, 226, 250, 330, 87, -1, + -1, 330, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 380, -1, -1, 383, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 394, -1, -1, -1, -1, + -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 410, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, -1, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 121, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 155, -1, 157, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 194, -1, -1, -1, -1, -1, 200, + 201, 202, 203, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 215, 216, 217, 3, 4, 5, + 6, 7, 8, 9, 10, 11, -1, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, + 106, -1, 108, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 121, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 155, + -1, 157, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 194, -1, + -1, -1, -1, -1, 200, 201, 202, 203, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, + 216, 217, 3, 4, 5, 6, 7, 8, 9, 10, + 11, -1, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, -1, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 121, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 155, -1, 157, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 194, -1, -1, -1, -1, -1, 200, + 201, 202, 203, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 215, 216, 217, 3, 4, 5, + 6, 7, 8, 9, 10, 11, -1, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, + 106, -1, 108, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 121, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 155, + -1, 157, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 194, -1, + -1, -1, -1, -1, 200, 201, 202, 203, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, + 216, 217, 3, 4, 5, 6, 7, 8, 9, 10, + 11, -1, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, -1, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 121, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 155, -1, 157, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 194, -1, -1, -1, -1, -1, 200, + 201, 202, 203, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 215, 216, 3, 4, 5, 6, + 7, 8, 9, 10, 11, -1, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, -1, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, -1, -1, 84, 85, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, + -1, 108, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 121, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 155, -1, + 157, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 194, -1, -1, + -1, -1, -1, 200, 201, 202, 203, 3, 4, 5, + 6, 7, 8, -1, -1, -1, -1, -1, 215, 216, + -1, -1, -1, -1, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, -1, + 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, + 106, -1, 108, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 121, 5, 6, 7, 8, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, -1, -1, -1, -1, -1, -1, 155, + -1, 157, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, -1, 76, 194, -1, + -1, -1, -1, -1, 200, 201, 202, 203, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, + -1, -1, -1, -1, -1, 104, 105, 106, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 5, 6, 7, 8, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + -1, -1, -1, -1, -1, -1, 155, -1, 157, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, -1, 76, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 217, -1, + -1, -1, 104, 105, 106, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, + -1, -1, -1, 155, -1, 157, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + -1, 76, 77, 78, 79, 80, 81, -1, -1, 84, + 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 217, -1, -1, -1, 104, + 105, 106, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 155, -1, 157, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 194, + -1, -1, -1, -1, -1, 200, 201, 202, 203, 3, + 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, + 215, -1, -1, -1, -1, -1, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, -1, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, -1, 76, 77, 78, 79, 80, 81, -1, -1, + 84, 85, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 103, + 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 121, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 155, -1, 157, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 5, 6, 7, 8, -1, + 194, -1, -1, -1, -1, -1, 200, 201, 202, 203, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, -1, 76, 77, 78, 79, + 80, 81, -1, -1, 84, 85, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 104, 105, 106, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 155, -1, 157, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, + 6, 7, 8, -1, 194, -1, -1, 197, -1, -1, + 200, 201, 202, 203, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, -1, + 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 104, 105, + 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 155, + -1, 157, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 5, 6, 7, 8, -1, 194, -1, + -1, 197, -1, -1, 200, 201, 202, 203, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, + -1, -1, 84, 85, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 104, 105, 106, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 155, -1, 157, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 5, 6, 7, + 8, -1, 194, -1, -1, 197, -1, -1, 200, 201, + 202, 203, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, -1, 76, 77, + 78, 79, 80, 81, -1, -1, 84, 85, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 104, 105, 106, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 155, -1, 157, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5, 6, 7, 8, -1, 194, -1, -1, -1, + -1, -1, 200, 201, 202, 203, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, -1, 76, 77, 78, 79, 80, 81, -1, -1, + 84, 85, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 155, -1, 157, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3, 4, 5, 6, 7, 8, -1, + 194, -1, -1, -1, -1, -1, 200, 201, 202, 203, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, -1, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, -1, 76, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 103, 104, 105, 106, -1, 108, -1, + -1, -1, -1, -1, -1, -1, 116, 117, 118, 119, + 120, 121, 5, 6, 7, 8, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, + -1, -1, -1, -1, -1, 155, -1, 157, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, -1, 76, 5, 6, 7, 8, 81, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 104, 105, 106, -1, -1, -1, -1, -1, -1, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, -1, 76, 5, 6, 7, 8, + -1, -1, 155, -1, 157, -1, -1, -1, -1, -1, + -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 104, 105, 106, -1, -1, -1, -1, + -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, -1, 76, -1, -1, + -1, -1, -1, -1, 155, -1, 157, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 155, -1, 157 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 109, 219, 221, 78, 0, 223, 113, 110, 220, + 224, 76, 3, 4, 5, 6, 7, 8, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 76, 103, 104, 105, 106, 108, 116, 117, + 118, 119, 120, 121, 155, 157, 222, 225, 255, 256, + 257, 258, 259, 264, 265, 266, 267, 270, 272, 273, + 274, 275, 276, 277, 278, 279, 303, 304, 112, 33, + 34, 37, 76, 216, 76, 270, 273, 278, 113, 113, + 113, 113, 113, 194, 303, 215, 216, 290, 195, 199, + 4, 33, 34, 35, 261, 262, 271, 199, 215, 76, + 273, 273, 274, 196, 275, 76, 216, 274, 280, 281, + 273, 275, 76, 268, 269, 9, 10, 11, 13, 14, + 15, 16, 17, 18, 19, 75, 76, 77, 78, 79, + 80, 81, 84, 85, 194, 200, 201, 202, 203, 215, + 216, 217, 226, 227, 228, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 253, 255, 256, + 274, 285, 286, 287, 288, 291, 292, 293, 296, 297, + 298, 302, 261, 260, 263, 274, 262, 76, 194, 196, + 214, 197, 237, 250, 254, 274, 113, 280, 76, 282, + 283, 217, 281, 215, 214, 195, 199, 215, 215, 286, + 194, 194, 215, 215, 253, 194, 253, 213, 194, 237, + 237, 253, 217, 291, 84, 85, 196, 198, 195, 195, + 199, 74, 251, 194, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 214, 252, 237, 204, 205, 206, + 200, 201, 82, 83, 86, 87, 207, 208, 88, 89, + 209, 210, 211, 90, 92, 91, 212, 199, 215, 217, + 286, 76, 260, 263, 196, 214, 197, 254, 251, 284, + 197, 217, 196, 199, 215, 78, 269, 75, 285, 292, + 299, 253, 215, 253, 213, 103, 253, 266, 295, 195, + 217, 229, 253, 76, 232, 251, 251, 237, 237, 237, + 239, 239, 240, 240, 241, 241, 241, 241, 242, 242, + 243, 244, 245, 246, 247, 248, 253, 251, 196, 197, + 254, 284, 214, 197, 254, 283, 194, 295, 300, 301, + 195, 195, 76, 195, 197, 213, 254, 214, 197, 284, + 214, 197, 253, 215, 195, 286, 294, 288, 214, 287, + 289, 290, 251, 197, 284, 214, 284, 195, 253, 289, + 12, 284, 284, 215, 286 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc, scanner) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, state); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + struct _mesa_glsl_parse_state *state; +#endif +{ + if (!yyvaluep) + return; + YYUSE (yylocationp); + YYUSE (state); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + struct _mesa_glsl_parse_state *state; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct _mesa_glsl_parse_state *state) +#else +static void +yy_reduce_print (yyvsp, yylsp, yyrule, state) + YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyrule; + struct _mesa_glsl_parse_state *state; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , state); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, Rule, state); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct _mesa_glsl_parse_state *state) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, state) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; + struct _mesa_glsl_parse_state *state; +#endif +{ + YYUSE (yyvaluep); + YYUSE (yylocationp); + YYUSE (state); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (struct _mesa_glsl_parse_state *state); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (struct _mesa_glsl_parse_state *state) +#else +int +yyparse (state) + struct _mesa_glsl_parse_state *state; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Location data for the lookahead symbol. */ +YYLTYPE yylloc; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + yylsp = yyls; + +#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + /* Initialize the default location before parsing starts. */ + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 1; +#endif + +/* User initialization code. */ + +/* Line 1251 of yacc.c */ +#line 41 "glsl_parser.ypp" +{ + yylloc.first_line = 1; + yylloc.first_column = 1; + yylloc.last_line = 1; + yylloc.last_column = 1; + yylloc.source = 0; +} + +/* Line 1251 of yacc.c */ +#line 2640 "glsl_parser.cpp" + yylsp[0] = yylloc; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + *++yylsp = yylloc; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: + +/* Line 1464 of yacc.c */ +#line 213 "glsl_parser.ypp" + { + _mesa_glsl_initialize_types(state); + ;} + break; + + case 5: + +/* Line 1464 of yacc.c */ +#line 222 "glsl_parser.ypp" + { + switch ((yyvsp[(2) - (3)].n)) { + case 100: + state->es_shader = true; + case 110: + case 120: + case 130: + /* FINISHME: Check against implementation support versions. */ + state->language_version = (yyvsp[(2) - (3)].n); + state->version_string = + talloc_asprintf(state, "GLSL%s %d.%02d", + state->es_shader ? " ES" : "", + state->language_version / 100, + state->language_version % 100); + break; + default: + _mesa_glsl_error(& (yylsp[(2) - (3)]), state, "Shading language version" + "%u is not supported\n", (yyvsp[(2) - (3)].n)); + break; + } + ;} + break; + + case 10: + +/* Line 1464 of yacc.c */ +#line 251 "glsl_parser.ypp" + { + if (state->language_version < 120) { + _mesa_glsl_warning(& (yylsp[(1) - (2)]), state, + "pragma `invariant(all)' not supported in %s", + state->version_string); + } else { + state->all_invariant = true; + } + ;} + break; + + case 13: + +/* Line 1464 of yacc.c */ +#line 269 "glsl_parser.ypp" + { + if (!_mesa_glsl_process_extension((yyvsp[(2) - (5)].identifier), & (yylsp[(2) - (5)]), (yyvsp[(4) - (5)].identifier), & (yylsp[(4) - (5)]), state)) { + YYERROR; + } + ;} + break; + + case 14: + +/* Line 1464 of yacc.c */ +#line 278 "glsl_parser.ypp" + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ((yyvsp[(1) - (1)].node) != NULL) + state->translation_unit.push_tail(& (yyvsp[(1) - (1)].node)->link); + ;} + break; + + case 15: + +/* Line 1464 of yacc.c */ +#line 286 "glsl_parser.ypp" + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ((yyvsp[(2) - (2)].node) != NULL) + state->translation_unit.push_tail(& (yyvsp[(2) - (2)].node)->link); + ;} + break; + + case 17: + +/* Line 1464 of yacc.c */ +#line 301 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.identifier = (yyvsp[(1) - (1)].identifier); + ;} + break; + + case 18: + +/* Line 1464 of yacc.c */ +#line 308 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.int_constant = (yyvsp[(1) - (1)].n); + ;} + break; + + case 19: + +/* Line 1464 of yacc.c */ +#line 315 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.uint_constant = (yyvsp[(1) - (1)].n); + ;} + break; + + case 20: + +/* Line 1464 of yacc.c */ +#line 322 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.float_constant = (yyvsp[(1) - (1)].real); + ;} + break; + + case 21: + +/* Line 1464 of yacc.c */ +#line 329 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.bool_constant = (yyvsp[(1) - (1)].n); + ;} + break; + + case 22: + +/* Line 1464 of yacc.c */ +#line 336 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(2) - (3)].expression); + ;} + break; + + case 24: + +/* Line 1464 of yacc.c */ +#line 344 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_array_index, (yyvsp[(1) - (4)].expression), (yyvsp[(3) - (4)].expression), NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 25: + +/* Line 1464 of yacc.c */ +#line 350 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (1)].expression); + ;} + break; + + case 26: + +/* Line 1464 of yacc.c */ +#line 354 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.identifier = (yyvsp[(3) - (3)].identifier); + ;} + break; + + case 27: + +/* Line 1464 of yacc.c */ +#line 361 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_post_inc, (yyvsp[(1) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 28: + +/* Line 1464 of yacc.c */ +#line 367 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_post_dec, (yyvsp[(1) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 32: + +/* Line 1464 of yacc.c */ +#line 385 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 37: + +/* Line 1464 of yacc.c */ +#line 404 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (2)].expression); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(2) - (2)].expression)->link); + ;} + break; + + case 38: + +/* Line 1464 of yacc.c */ +#line 410 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (3)].expression); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); + ;} + break; + + case 40: + +/* Line 1464 of yacc.c */ +#line 426 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_function_expression((yyvsp[(1) - (1)].type_specifier)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 41: + +/* Line 1464 of yacc.c */ +#line 432 "glsl_parser.ypp" + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); + (yyval.expression) = new(ctx) ast_function_expression(callee); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 42: + +/* Line 1464 of yacc.c */ +#line 439 "glsl_parser.ypp" + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); + (yyval.expression) = new(ctx) ast_function_expression(callee); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 44: + +/* Line 1464 of yacc.c */ +#line 451 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_pre_inc, (yyvsp[(2) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 45: + +/* Line 1464 of yacc.c */ +#line 457 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_pre_dec, (yyvsp[(2) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 46: + +/* Line 1464 of yacc.c */ +#line 463 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 47: + +/* Line 1464 of yacc.c */ +#line 472 "glsl_parser.ypp" + { (yyval.n) = ast_plus; ;} + break; + + case 48: + +/* Line 1464 of yacc.c */ +#line 473 "glsl_parser.ypp" + { (yyval.n) = ast_neg; ;} + break; + + case 49: + +/* Line 1464 of yacc.c */ +#line 474 "glsl_parser.ypp" + { (yyval.n) = ast_logic_not; ;} + break; + + case 50: + +/* Line 1464 of yacc.c */ +#line 475 "glsl_parser.ypp" + { (yyval.n) = ast_bit_not; ;} + break; + + case 52: + +/* Line 1464 of yacc.c */ +#line 481 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_mul, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 53: + +/* Line 1464 of yacc.c */ +#line 487 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_div, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 54: + +/* Line 1464 of yacc.c */ +#line 493 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_mod, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 56: + +/* Line 1464 of yacc.c */ +#line 503 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_add, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 57: + +/* Line 1464 of yacc.c */ +#line 509 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_sub, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 59: + +/* Line 1464 of yacc.c */ +#line 519 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_lshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 60: + +/* Line 1464 of yacc.c */ +#line 525 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_rshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 62: + +/* Line 1464 of yacc.c */ +#line 535 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_less, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 63: + +/* Line 1464 of yacc.c */ +#line 541 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_greater, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 64: + +/* Line 1464 of yacc.c */ +#line 547 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_lequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 65: + +/* Line 1464 of yacc.c */ +#line 553 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_gequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 67: + +/* Line 1464 of yacc.c */ +#line 563 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_equal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 68: + +/* Line 1464 of yacc.c */ +#line 569 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_nequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 70: + +/* Line 1464 of yacc.c */ +#line 579 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 72: + +/* Line 1464 of yacc.c */ +#line 589 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 74: + +/* Line 1464 of yacc.c */ +#line 599 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 76: + +/* Line 1464 of yacc.c */ +#line 609 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 78: + +/* Line 1464 of yacc.c */ +#line 619 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 80: + +/* Line 1464 of yacc.c */ +#line 629 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 82: + +/* Line 1464 of yacc.c */ +#line 639 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_conditional, (yyvsp[(1) - (5)].expression), (yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 84: + +/* Line 1464 of yacc.c */ +#line 649 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression((yyvsp[(2) - (3)].n), (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 85: + +/* Line 1464 of yacc.c */ +#line 657 "glsl_parser.ypp" + { (yyval.n) = ast_assign; ;} + break; + + case 86: + +/* Line 1464 of yacc.c */ +#line 658 "glsl_parser.ypp" + { (yyval.n) = ast_mul_assign; ;} + break; + + case 87: + +/* Line 1464 of yacc.c */ +#line 659 "glsl_parser.ypp" + { (yyval.n) = ast_div_assign; ;} + break; + + case 88: + +/* Line 1464 of yacc.c */ +#line 660 "glsl_parser.ypp" + { (yyval.n) = ast_mod_assign; ;} + break; + + case 89: + +/* Line 1464 of yacc.c */ +#line 661 "glsl_parser.ypp" + { (yyval.n) = ast_add_assign; ;} + break; + + case 90: + +/* Line 1464 of yacc.c */ +#line 662 "glsl_parser.ypp" + { (yyval.n) = ast_sub_assign; ;} + break; + + case 91: + +/* Line 1464 of yacc.c */ +#line 663 "glsl_parser.ypp" + { (yyval.n) = ast_ls_assign; ;} + break; + + case 92: + +/* Line 1464 of yacc.c */ +#line 664 "glsl_parser.ypp" + { (yyval.n) = ast_rs_assign; ;} + break; + + case 93: + +/* Line 1464 of yacc.c */ +#line 665 "glsl_parser.ypp" + { (yyval.n) = ast_and_assign; ;} + break; + + case 94: + +/* Line 1464 of yacc.c */ +#line 666 "glsl_parser.ypp" + { (yyval.n) = ast_xor_assign; ;} + break; + + case 95: + +/* Line 1464 of yacc.c */ +#line 667 "glsl_parser.ypp" + { (yyval.n) = ast_or_assign; ;} + break; + + case 96: + +/* Line 1464 of yacc.c */ +#line 672 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (1)].expression); + ;} + break; + + case 97: + +/* Line 1464 of yacc.c */ +#line 676 "glsl_parser.ypp" + { + void *ctx = state; + if ((yyvsp[(1) - (3)].expression)->oper != ast_sequence) { + (yyval.expression) = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(1) - (3)].expression)->link); + } else { + (yyval.expression) = (yyvsp[(1) - (3)].expression); + } + + (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); + ;} + break; + + case 99: + +/* Line 1464 of yacc.c */ +#line 696 "glsl_parser.ypp" + { + (yyval.node) = (yyvsp[(1) - (2)].function); + ;} + break; + + case 100: + +/* Line 1464 of yacc.c */ +#line 700 "glsl_parser.ypp" + { + (yyval.node) = (yyvsp[(1) - (2)].declarator_list); + ;} + break; + + case 101: + +/* Line 1464 of yacc.c */ +#line 704 "glsl_parser.ypp" + { + (yyvsp[(3) - (4)].type_specifier)->precision = (yyvsp[(2) - (4)].n); + (yyvsp[(3) - (4)].type_specifier)->is_precision_statement = true; + (yyval.node) = (yyvsp[(3) - (4)].type_specifier); + ;} + break; + + case 105: + +/* Line 1464 of yacc.c */ +#line 722 "glsl_parser.ypp" + { + (yyval.function) = (yyvsp[(1) - (2)].function); + (yyval.function)->parameters.push_tail(& (yyvsp[(2) - (2)].parameter_declarator)->link); + ;} + break; + + case 106: + +/* Line 1464 of yacc.c */ +#line 727 "glsl_parser.ypp" + { + (yyval.function) = (yyvsp[(1) - (3)].function); + (yyval.function)->parameters.push_tail(& (yyvsp[(3) - (3)].parameter_declarator)->link); + ;} + break; + + case 107: + +/* Line 1464 of yacc.c */ +#line 735 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.function) = new(ctx) ast_function(); + (yyval.function)->set_location(yylloc); + (yyval.function)->return_type = (yyvsp[(1) - (3)].fully_specified_type); + (yyval.function)->identifier = (yyvsp[(2) - (3)].identifier); + ;} + break; + + case 108: + +/* Line 1464 of yacc.c */ +#line 746 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->set_location(yylloc); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (2)].type_specifier); + (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (2)].identifier); + ;} + break; + + case 109: + +/* Line 1464 of yacc.c */ +#line 756 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->set_location(yylloc); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (5)].type_specifier); + (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (5)].identifier); + (yyval.parameter_declarator)->is_array = true; + (yyval.parameter_declarator)->array_size = (yyvsp[(4) - (5)].expression); + ;} + break; + + case 110: + +/* Line 1464 of yacc.c */ +#line 771 "glsl_parser.ypp" + { + (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i; + + (yyval.parameter_declarator) = (yyvsp[(3) - (3)].parameter_declarator); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier); + ;} + break; + + case 111: + +/* Line 1464 of yacc.c */ +#line 778 "glsl_parser.ypp" + { + (yyval.parameter_declarator) = (yyvsp[(2) - (2)].parameter_declarator); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier); + ;} + break; + + case 112: + +/* Line 1464 of yacc.c */ +#line 783 "glsl_parser.ypp" + { + void *ctx = state; + (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i; + + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(3) - (3)].type_specifier); + ;} + break; + + case 113: + +/* Line 1464 of yacc.c */ +#line 794 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(2) - (2)].type_specifier); + ;} + break; + + case 114: + +/* Line 1464 of yacc.c */ +#line 806 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + ;} + break; + + case 115: + +/* Line 1464 of yacc.c */ +#line 810 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.in = 1; + ;} + break; + + case 116: + +/* Line 1464 of yacc.c */ +#line 815 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 117: + +/* Line 1464 of yacc.c */ +#line 820 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.in = 1; + (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 120: + +/* Line 1464 of yacc.c */ +#line 834 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (3)].identifier), false, NULL, NULL); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (3)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 121: + +/* Line 1464 of yacc.c */ +#line 843 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), true, NULL, NULL); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 122: + +/* Line 1464 of yacc.c */ +#line 852 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (6)].identifier), true, (yyvsp[(5) - (6)].expression), NULL); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (6)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 123: + +/* Line 1464 of yacc.c */ +#line 861 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (7)].identifier), true, NULL, (yyvsp[(7) - (7)].expression)); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (7)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 124: + +/* Line 1464 of yacc.c */ +#line 870 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (8)].identifier), true, (yyvsp[(5) - (8)].expression), (yyvsp[(8) - (8)].expression)); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (8)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 125: + +/* Line 1464 of yacc.c */ +#line 879 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), false, NULL, (yyvsp[(5) - (5)].expression)); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 126: + +/* Line 1464 of yacc.c */ +#line 892 "glsl_parser.ypp" + { + void *ctx = state; + if ((yyvsp[(1) - (1)].fully_specified_type)->specifier->type_specifier != ast_struct) { + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "empty declaration list\n"); + YYERROR; + } else { + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (1)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + } + ;} + break; + + case 127: + +/* Line 1464 of yacc.c */ +#line 903 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (2)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 128: + +/* Line 1464 of yacc.c */ +#line 912 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), true, NULL, NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 129: + +/* Line 1464 of yacc.c */ +#line 921 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (5)].identifier), true, (yyvsp[(4) - (5)].expression), NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (5)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 130: + +/* Line 1464 of yacc.c */ +#line 930 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (6)].identifier), true, NULL, (yyvsp[(6) - (6)].expression)); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (6)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 131: + +/* Line 1464 of yacc.c */ +#line 939 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (7)].identifier), true, (yyvsp[(4) - (7)].expression), (yyvsp[(7) - (7)].expression)); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (7)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 132: + +/* Line 1464 of yacc.c */ +#line 948 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 133: + +/* Line 1464 of yacc.c */ +#line 957 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list(NULL); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->invariant = true; + + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 134: + +/* Line 1464 of yacc.c */ +#line 971 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); + (yyval.fully_specified_type)->set_location(yylloc); + (yyval.fully_specified_type)->specifier = (yyvsp[(1) - (1)].type_specifier); + ;} + break; + + case 135: + +/* Line 1464 of yacc.c */ +#line 978 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); + (yyval.fully_specified_type)->set_location(yylloc); + (yyval.fully_specified_type)->qualifier = (yyvsp[(1) - (2)].type_qualifier); + (yyval.fully_specified_type)->specifier = (yyvsp[(2) - (2)].type_specifier); + ;} + break; + + case 136: + +/* Line 1464 of yacc.c */ +#line 989 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(3) - (4)].type_qualifier); + ;} + break; + + case 138: + +/* Line 1464 of yacc.c */ +#line 997 "glsl_parser.ypp" + { + if (((yyvsp[(1) - (3)].type_qualifier).flags.i & (yyvsp[(3) - (3)].type_qualifier).flags.i) != 0) { + _mesa_glsl_error(& (yylsp[(3) - (3)]), state, + "duplicate layout qualifiers used\n"); + YYERROR; + } + + (yyval.type_qualifier).flags.i = (yyvsp[(1) - (3)].type_qualifier).flags.i | (yyvsp[(3) - (3)].type_qualifier).flags.i; + + if ((yyvsp[(1) - (3)].type_qualifier).flags.q.explicit_location) + (yyval.type_qualifier).location = (yyvsp[(1) - (3)].type_qualifier).location; + + if ((yyvsp[(3) - (3)].type_qualifier).flags.q.explicit_location) + (yyval.type_qualifier).location = (yyvsp[(3) - (3)].type_qualifier).location; + ;} + break; + + case 139: + +/* Line 1464 of yacc.c */ +#line 1016 "glsl_parser.ypp" + { + bool got_one = false; + + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + + if (state->ARB_fragment_coord_conventions_enable) { + if (strcmp((yyvsp[(1) - (1)].identifier), "origin_upper_left") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.origin_upper_left = 1; + } else if (strcmp((yyvsp[(1) - (1)].identifier), "pixel_center_integer") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.pixel_center_integer = 1; + } + } + + /* If the identifier didn't match any known layout identifiers, + * emit an error. + */ + if (!got_one) { + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "unrecognized layout identifier " + "`%s'\n", (yyvsp[(1) - (1)].identifier)); + YYERROR; + } else if (state->ARB_fragment_coord_conventions_warn) { + _mesa_glsl_warning(& (yylsp[(1) - (1)]), state, + "GL_ARB_fragment_coord_conventions layout " + "identifier `%s' used\n", (yyvsp[(1) - (1)].identifier)); + } + ;} + break; + + case 140: + +/* Line 1464 of yacc.c */ +#line 1045 "glsl_parser.ypp" + { + bool got_one = false; + + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + + if (state->ARB_explicit_attrib_location_enable) { + /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and + * FINISHME: GLSL 1.30 (or later) are supported. + */ + if (strcmp("location", (yyvsp[(1) - (3)].identifier)) == 0) { + got_one = true; + + (yyval.type_qualifier).flags.q.explicit_location = 1; + + if ((yyvsp[(3) - (3)].n) >= 0) { + (yyval.type_qualifier).location = (yyvsp[(3) - (3)].n); + } else { + _mesa_glsl_error(& (yylsp[(3) - (3)]), state, + "invalid location %d specified\n", (yyvsp[(3) - (3)].n)); + YYERROR; + } + } + } + + /* If the identifier didn't match any known layout identifiers, + * emit an error. + */ + if (!got_one) { + _mesa_glsl_error(& (yylsp[(1) - (3)]), state, "unrecognized layout identifier " + "`%s'\n", (yyvsp[(1) - (3)].identifier)); + YYERROR; + } else if (state->ARB_explicit_attrib_location_warn) { + _mesa_glsl_warning(& (yylsp[(1) - (3)]), state, + "GL_ARB_explicit_attrib_location layout " + "identifier `%s' used\n", (yyvsp[(1) - (3)].identifier)); + } + ;} + break; + + case 141: + +/* Line 1464 of yacc.c */ +#line 1086 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.smooth = 1; + ;} + break; + + case 142: + +/* Line 1464 of yacc.c */ +#line 1091 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.flat = 1; + ;} + break; + + case 143: + +/* Line 1464 of yacc.c */ +#line 1096 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.noperspective = 1; + ;} + break; + + case 144: + +/* Line 1464 of yacc.c */ +#line 1104 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.constant = 1; + ;} + break; + + case 147: + +/* Line 1464 of yacc.c */ +#line 1114 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier); + (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i; + ;} + break; + + case 149: + +/* Line 1464 of yacc.c */ +#line 1120 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier); + (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i; + ;} + break; + + case 150: + +/* Line 1464 of yacc.c */ +#line 1125 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(2) - (2)].type_qualifier); + (yyval.type_qualifier).flags.q.invariant = 1; + ;} + break; + + case 151: + +/* Line 1464 of yacc.c */ +#line 1130 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(2) - (3)].type_qualifier); + (yyval.type_qualifier).flags.i |= (yyvsp[(3) - (3)].type_qualifier).flags.i; + (yyval.type_qualifier).flags.q.invariant = 1; + ;} + break; + + case 152: + +/* Line 1464 of yacc.c */ +#line 1136 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.invariant = 1; + ;} + break; + + case 153: + +/* Line 1464 of yacc.c */ +#line 1144 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.constant = 1; + ;} + break; + + case 154: + +/* Line 1464 of yacc.c */ +#line 1149 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.attribute = 1; + ;} + break; + + case 155: + +/* Line 1464 of yacc.c */ +#line 1154 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.varying = 1; + ;} + break; + + case 156: + +/* Line 1464 of yacc.c */ +#line 1159 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.centroid = 1; + (yyval.type_qualifier).flags.q.varying = 1; + ;} + break; + + case 157: + +/* Line 1464 of yacc.c */ +#line 1165 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.in = 1; + ;} + break; + + case 158: + +/* Line 1464 of yacc.c */ +#line 1170 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 159: + +/* Line 1464 of yacc.c */ +#line 1175 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.in = 1; + ;} + break; + + case 160: + +/* Line 1464 of yacc.c */ +#line 1180 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 161: + +/* Line 1464 of yacc.c */ +#line 1185 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.uniform = 1; + ;} + break; + + case 162: + +/* Line 1464 of yacc.c */ +#line 1193 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(1) - (1)].type_specifier); + ;} + break; + + case 163: + +/* Line 1464 of yacc.c */ +#line 1197 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(2) - (2)].type_specifier); + (yyval.type_specifier)->precision = (yyvsp[(1) - (2)].n); + ;} + break; + + case 165: + +/* Line 1464 of yacc.c */ +#line 1206 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(1) - (3)].type_specifier); + (yyval.type_specifier)->is_array = true; + (yyval.type_specifier)->array_size = NULL; + ;} + break; + + case 166: + +/* Line 1464 of yacc.c */ +#line 1212 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(1) - (4)].type_specifier); + (yyval.type_specifier)->is_array = true; + (yyval.type_specifier)->array_size = (yyvsp[(3) - (4)].expression); + ;} + break; + + case 167: + +/* Line 1464 of yacc.c */ +#line 1221 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].n)); + (yyval.type_specifier)->set_location(yylloc); + ;} + break; + + case 168: + +/* Line 1464 of yacc.c */ +#line 1227 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].struct_specifier)); + (yyval.type_specifier)->set_location(yylloc); + ;} + break; + + case 169: + +/* Line 1464 of yacc.c */ +#line 1233 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].identifier)); + (yyval.type_specifier)->set_location(yylloc); + ;} + break; + + case 170: + +/* Line 1464 of yacc.c */ +#line 1241 "glsl_parser.ypp" + { (yyval.n) = ast_void; ;} + break; + + case 171: + +/* Line 1464 of yacc.c */ +#line 1242 "glsl_parser.ypp" + { (yyval.n) = ast_float; ;} + break; + + case 172: + +/* Line 1464 of yacc.c */ +#line 1243 "glsl_parser.ypp" + { (yyval.n) = ast_int; ;} + break; + + case 173: + +/* Line 1464 of yacc.c */ +#line 1244 "glsl_parser.ypp" + { (yyval.n) = ast_uint; ;} + break; + + case 174: + +/* Line 1464 of yacc.c */ +#line 1245 "glsl_parser.ypp" + { (yyval.n) = ast_bool; ;} + break; + + case 175: + +/* Line 1464 of yacc.c */ +#line 1246 "glsl_parser.ypp" + { (yyval.n) = ast_vec2; ;} + break; + + case 176: + +/* Line 1464 of yacc.c */ +#line 1247 "glsl_parser.ypp" + { (yyval.n) = ast_vec3; ;} + break; + + case 177: + +/* Line 1464 of yacc.c */ +#line 1248 "glsl_parser.ypp" + { (yyval.n) = ast_vec4; ;} + break; + + case 178: + +/* Line 1464 of yacc.c */ +#line 1249 "glsl_parser.ypp" + { (yyval.n) = ast_bvec2; ;} + break; + + case 179: + +/* Line 1464 of yacc.c */ +#line 1250 "glsl_parser.ypp" + { (yyval.n) = ast_bvec3; ;} + break; + + case 180: + +/* Line 1464 of yacc.c */ +#line 1251 "glsl_parser.ypp" + { (yyval.n) = ast_bvec4; ;} + break; + + case 181: + +/* Line 1464 of yacc.c */ +#line 1252 "glsl_parser.ypp" + { (yyval.n) = ast_ivec2; ;} + break; + + case 182: + +/* Line 1464 of yacc.c */ +#line 1253 "glsl_parser.ypp" + { (yyval.n) = ast_ivec3; ;} + break; + + case 183: + +/* Line 1464 of yacc.c */ +#line 1254 "glsl_parser.ypp" + { (yyval.n) = ast_ivec4; ;} + break; + + case 184: + +/* Line 1464 of yacc.c */ +#line 1255 "glsl_parser.ypp" + { (yyval.n) = ast_uvec2; ;} + break; + + case 185: + +/* Line 1464 of yacc.c */ +#line 1256 "glsl_parser.ypp" + { (yyval.n) = ast_uvec3; ;} + break; + + case 186: + +/* Line 1464 of yacc.c */ +#line 1257 "glsl_parser.ypp" + { (yyval.n) = ast_uvec4; ;} + break; + + case 187: + +/* Line 1464 of yacc.c */ +#line 1258 "glsl_parser.ypp" + { (yyval.n) = ast_mat2; ;} + break; + + case 188: + +/* Line 1464 of yacc.c */ +#line 1259 "glsl_parser.ypp" + { (yyval.n) = ast_mat2x3; ;} + break; + + case 189: + +/* Line 1464 of yacc.c */ +#line 1260 "glsl_parser.ypp" + { (yyval.n) = ast_mat2x4; ;} + break; + + case 190: + +/* Line 1464 of yacc.c */ +#line 1261 "glsl_parser.ypp" + { (yyval.n) = ast_mat3x2; ;} + break; + + case 191: + +/* Line 1464 of yacc.c */ +#line 1262 "glsl_parser.ypp" + { (yyval.n) = ast_mat3; ;} + break; + + case 192: + +/* Line 1464 of yacc.c */ +#line 1263 "glsl_parser.ypp" + { (yyval.n) = ast_mat3x4; ;} + break; + + case 193: + +/* Line 1464 of yacc.c */ +#line 1264 "glsl_parser.ypp" + { (yyval.n) = ast_mat4x2; ;} + break; + + case 194: + +/* Line 1464 of yacc.c */ +#line 1265 "glsl_parser.ypp" + { (yyval.n) = ast_mat4x3; ;} + break; + + case 195: + +/* Line 1464 of yacc.c */ +#line 1266 "glsl_parser.ypp" + { (yyval.n) = ast_mat4; ;} + break; + + case 196: + +/* Line 1464 of yacc.c */ +#line 1267 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1d; ;} + break; + + case 197: + +/* Line 1464 of yacc.c */ +#line 1268 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2d; ;} + break; + + case 198: + +/* Line 1464 of yacc.c */ +#line 1269 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2drect; ;} + break; + + case 199: + +/* Line 1464 of yacc.c */ +#line 1270 "glsl_parser.ypp" + { (yyval.n) = ast_sampler3d; ;} + break; + + case 200: + +/* Line 1464 of yacc.c */ +#line 1271 "glsl_parser.ypp" + { (yyval.n) = ast_samplercube; ;} + break; + + case 201: + +/* Line 1464 of yacc.c */ +#line 1272 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1dshadow; ;} + break; + + case 202: + +/* Line 1464 of yacc.c */ +#line 1273 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2dshadow; ;} + break; + + case 203: + +/* Line 1464 of yacc.c */ +#line 1274 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2drectshadow; ;} + break; + + case 204: + +/* Line 1464 of yacc.c */ +#line 1275 "glsl_parser.ypp" + { (yyval.n) = ast_samplercubeshadow; ;} + break; + + case 205: + +/* Line 1464 of yacc.c */ +#line 1276 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1darray; ;} + break; + + case 206: + +/* Line 1464 of yacc.c */ +#line 1277 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2darray; ;} + break; + + case 207: + +/* Line 1464 of yacc.c */ +#line 1278 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1darrayshadow; ;} + break; + + case 208: + +/* Line 1464 of yacc.c */ +#line 1279 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2darrayshadow; ;} + break; + + case 209: + +/* Line 1464 of yacc.c */ +#line 1280 "glsl_parser.ypp" + { (yyval.n) = ast_isampler1d; ;} + break; + + case 210: + +/* Line 1464 of yacc.c */ +#line 1281 "glsl_parser.ypp" + { (yyval.n) = ast_isampler2d; ;} + break; + + case 211: + +/* Line 1464 of yacc.c */ +#line 1282 "glsl_parser.ypp" + { (yyval.n) = ast_isampler3d; ;} + break; + + case 212: + +/* Line 1464 of yacc.c */ +#line 1283 "glsl_parser.ypp" + { (yyval.n) = ast_isamplercube; ;} + break; + + case 213: + +/* Line 1464 of yacc.c */ +#line 1284 "glsl_parser.ypp" + { (yyval.n) = ast_isampler1darray; ;} + break; + + case 214: + +/* Line 1464 of yacc.c */ +#line 1285 "glsl_parser.ypp" + { (yyval.n) = ast_isampler2darray; ;} + break; + + case 215: + +/* Line 1464 of yacc.c */ +#line 1286 "glsl_parser.ypp" + { (yyval.n) = ast_usampler1d; ;} + break; + + case 216: + +/* Line 1464 of yacc.c */ +#line 1287 "glsl_parser.ypp" + { (yyval.n) = ast_usampler2d; ;} + break; + + case 217: + +/* Line 1464 of yacc.c */ +#line 1288 "glsl_parser.ypp" + { (yyval.n) = ast_usampler3d; ;} + break; + + case 218: + +/* Line 1464 of yacc.c */ +#line 1289 "glsl_parser.ypp" + { (yyval.n) = ast_usamplercube; ;} + break; + + case 219: + +/* Line 1464 of yacc.c */ +#line 1290 "glsl_parser.ypp" + { (yyval.n) = ast_usampler1darray; ;} + break; + + case 220: + +/* Line 1464 of yacc.c */ +#line 1291 "glsl_parser.ypp" + { (yyval.n) = ast_usampler2darray; ;} + break; + + case 221: + +/* Line 1464 of yacc.c */ +#line 1295 "glsl_parser.ypp" + { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + (yyval.n) = ast_precision_high; + ;} + break; + + case 222: + +/* Line 1464 of yacc.c */ +#line 1305 "glsl_parser.ypp" + { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + (yyval.n) = ast_precision_medium; + ;} + break; + + case 223: + +/* Line 1464 of yacc.c */ +#line 1315 "glsl_parser.ypp" + { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + (yyval.n) = ast_precision_low; + ;} + break; + + case 224: + +/* Line 1464 of yacc.c */ +#line 1329 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.struct_specifier) = new(ctx) ast_struct_specifier((yyvsp[(2) - (5)].identifier), (yyvsp[(4) - (5)].node)); + (yyval.struct_specifier)->set_location(yylloc); + ;} + break; + + case 225: + +/* Line 1464 of yacc.c */ +#line 1335 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.struct_specifier) = new(ctx) ast_struct_specifier(NULL, (yyvsp[(3) - (4)].node)); + (yyval.struct_specifier)->set_location(yylloc); + ;} + break; + + case 226: + +/* Line 1464 of yacc.c */ +#line 1344 "glsl_parser.ypp" + { + (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list); + (yyvsp[(1) - (1)].declarator_list)->link.self_link(); + ;} + break; + + case 227: + +/* Line 1464 of yacc.c */ +#line 1349 "glsl_parser.ypp" + { + (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node); + (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link); + ;} + break; + + case 228: + +/* Line 1464 of yacc.c */ +#line 1357 "glsl_parser.ypp" + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->specifier = (yyvsp[(1) - (3)].type_specifier); + (yyval.declarator_list) = new(ctx) ast_declarator_list(type); + (yyval.declarator_list)->set_location(yylloc); + + (yyval.declarator_list)->declarations.push_degenerate_list_at_head(& (yyvsp[(2) - (3)].declaration)->link); + ;} + break; + + case 229: + +/* Line 1464 of yacc.c */ +#line 1372 "glsl_parser.ypp" + { + (yyval.declaration) = (yyvsp[(1) - (1)].declaration); + (yyvsp[(1) - (1)].declaration)->link.self_link(); + ;} + break; + + case 230: + +/* Line 1464 of yacc.c */ +#line 1377 "glsl_parser.ypp" + { + (yyval.declaration) = (yyvsp[(1) - (3)].declaration); + (yyval.declaration)->link.insert_before(& (yyvsp[(3) - (3)].declaration)->link); + ;} + break; + + case 231: + +/* Line 1464 of yacc.c */ +#line 1385 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (1)].identifier), false, NULL, NULL); + (yyval.declaration)->set_location(yylloc); + ;} + break; + + case 232: + +/* Line 1464 of yacc.c */ +#line 1391 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (4)].identifier), true, (yyvsp[(3) - (4)].expression), NULL); + (yyval.declaration)->set_location(yylloc); + ;} + break; + + case 235: + +/* Line 1464 of yacc.c */ +#line 1409 "glsl_parser.ypp" + { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} + break; + + case 240: + +/* Line 1464 of yacc.c */ +#line 1417 "glsl_parser.ypp" + { (yyval.node) = NULL; ;} + break; + + case 241: + +/* Line 1464 of yacc.c */ +#line 1418 "glsl_parser.ypp" + { (yyval.node) = NULL; ;} + break; + + case 244: + +/* Line 1464 of yacc.c */ +#line 1425 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(true, NULL); + (yyval.compound_statement)->set_location(yylloc); + ;} + break; + + case 245: + +/* Line 1464 of yacc.c */ +#line 1431 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(true, (yyvsp[(2) - (3)].node)); + (yyval.compound_statement)->set_location(yylloc); + ;} + break; + + case 246: + +/* Line 1464 of yacc.c */ +#line 1439 "glsl_parser.ypp" + { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} + break; + + case 248: + +/* Line 1464 of yacc.c */ +#line 1445 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(false, NULL); + (yyval.compound_statement)->set_location(yylloc); + ;} + break; + + case 249: + +/* Line 1464 of yacc.c */ +#line 1451 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(false, (yyvsp[(2) - (3)].node)); + (yyval.compound_statement)->set_location(yylloc); + ;} + break; + + case 250: + +/* Line 1464 of yacc.c */ +#line 1460 "glsl_parser.ypp" + { + if ((yyvsp[(1) - (1)].node) == NULL) { + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "<nil> statement\n"); + assert((yyvsp[(1) - (1)].node) != NULL); + } + + (yyval.node) = (yyvsp[(1) - (1)].node); + (yyval.node)->link.self_link(); + ;} + break; + + case 251: + +/* Line 1464 of yacc.c */ +#line 1470 "glsl_parser.ypp" + { + if ((yyvsp[(2) - (2)].node) == NULL) { + _mesa_glsl_error(& (yylsp[(2) - (2)]), state, "<nil> statement\n"); + assert((yyvsp[(2) - (2)].node) != NULL); + } + (yyval.node) = (yyvsp[(1) - (2)].node); + (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].node)->link); + ;} + break; + + case 252: + +/* Line 1464 of yacc.c */ +#line 1482 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_expression_statement(NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 253: + +/* Line 1464 of yacc.c */ +#line 1488 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_expression_statement((yyvsp[(1) - (2)].expression)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 254: + +/* Line 1464 of yacc.c */ +#line 1497 "glsl_parser.ypp" + { + (yyval.node) = new(state) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].selection_rest_statement).then_statement, + (yyvsp[(5) - (5)].selection_rest_statement).else_statement); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 255: + +/* Line 1464 of yacc.c */ +#line 1506 "glsl_parser.ypp" + { + (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (3)].node); + (yyval.selection_rest_statement).else_statement = (yyvsp[(3) - (3)].node); + ;} + break; + + case 256: + +/* Line 1464 of yacc.c */ +#line 1511 "glsl_parser.ypp" + { + (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (1)].node); + (yyval.selection_rest_statement).else_statement = NULL; + ;} + break; + + case 257: + +/* Line 1464 of yacc.c */ +#line 1519 "glsl_parser.ypp" + { + (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression); + ;} + break; + + case 258: + +/* Line 1464 of yacc.c */ +#line 1523 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); + ast_declarator_list *declarator = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); + decl->set_location(yylloc); + declarator->set_location(yylloc); + + declarator->declarations.push_tail(&decl->link); + (yyval.node) = declarator; + ;} + break; + + case 262: + +/* Line 1464 of yacc.c */ +#line 1546 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, + NULL, (yyvsp[(3) - (5)].node), NULL, (yyvsp[(5) - (5)].node)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 263: + +/* Line 1464 of yacc.c */ +#line 1553 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, + NULL, (yyvsp[(5) - (7)].expression), NULL, (yyvsp[(2) - (7)].node)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 264: + +/* Line 1464 of yacc.c */ +#line 1560 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, + (yyvsp[(3) - (6)].node), (yyvsp[(4) - (6)].for_rest_statement).cond, (yyvsp[(4) - (6)].for_rest_statement).rest, (yyvsp[(6) - (6)].node)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 268: + +/* Line 1464 of yacc.c */ +#line 1576 "glsl_parser.ypp" + { + (yyval.node) = NULL; + ;} + break; + + case 269: + +/* Line 1464 of yacc.c */ +#line 1583 "glsl_parser.ypp" + { + (yyval.for_rest_statement).cond = (yyvsp[(1) - (2)].node); + (yyval.for_rest_statement).rest = NULL; + ;} + break; + + case 270: + +/* Line 1464 of yacc.c */ +#line 1588 "glsl_parser.ypp" + { + (yyval.for_rest_statement).cond = (yyvsp[(1) - (3)].node); + (yyval.for_rest_statement).rest = (yyvsp[(3) - (3)].expression); + ;} + break; + + case 271: + +/* Line 1464 of yacc.c */ +#line 1597 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 272: + +/* Line 1464 of yacc.c */ +#line 1603 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 273: + +/* Line 1464 of yacc.c */ +#line 1609 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 274: + +/* Line 1464 of yacc.c */ +#line 1615 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, (yyvsp[(2) - (3)].expression)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 275: + +/* Line 1464 of yacc.c */ +#line 1621 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 276: + +/* Line 1464 of yacc.c */ +#line 1629 "glsl_parser.ypp" + { (yyval.node) = (yyvsp[(1) - (1)].function_definition); ;} + break; + + case 277: + +/* Line 1464 of yacc.c */ +#line 1630 "glsl_parser.ypp" + { (yyval.node) = (yyvsp[(1) - (1)].node); ;} + break; + + case 278: + +/* Line 1464 of yacc.c */ +#line 1631 "glsl_parser.ypp" + { (yyval.node) = NULL; ;} + break; + + case 279: + +/* Line 1464 of yacc.c */ +#line 1636 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.function_definition) = new(ctx) ast_function_definition(); + (yyval.function_definition)->set_location(yylloc); + (yyval.function_definition)->prototype = (yyvsp[(1) - (2)].function); + (yyval.function_definition)->body = (yyvsp[(2) - (2)].compound_statement); + ;} + break; + + + +/* Line 1464 of yacc.c */ +#line 5116 "glsl_parser.cpp" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + *++yylsp = yyloc; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (&yylloc, state, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (&yylloc, state, yymsg); + } + else + { + yyerror (&yylloc, state, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + yyerror_range[1] = yylloc; + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, state); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + yyerror_range[1] = yylsp[1-yylen]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", + yystos[yystate], yyvsp, yylsp, state); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + yyerror_range[2] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); + *++yylsp = yyloc; + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (&yylloc, state, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, state); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, yylsp, state); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + diff --git a/mesalib/src/glsl/glsl_parser.h b/mesalib/src/glsl/glsl_parser.h index d1f555d09..1bf3b3538 100644 --- a/mesalib/src/glsl/glsl_parser.h +++ b/mesalib/src/glsl/glsl_parser.h @@ -1,299 +1,298 @@ -
-/* A Bison parser, made by GNU Bison 2.4.1. */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- ATTRIBUTE = 258,
- CONST_TOK = 259,
- BOOL_TOK = 260,
- FLOAT_TOK = 261,
- INT_TOK = 262,
- UINT_TOK = 263,
- BREAK = 264,
- CONTINUE = 265,
- DO = 266,
- ELSE = 267,
- FOR = 268,
- IF = 269,
- DISCARD = 270,
- RETURN = 271,
- SWITCH = 272,
- CASE = 273,
- DEFAULT = 274,
- BVEC2 = 275,
- BVEC3 = 276,
- BVEC4 = 277,
- IVEC2 = 278,
- IVEC3 = 279,
- IVEC4 = 280,
- UVEC2 = 281,
- UVEC3 = 282,
- UVEC4 = 283,
- VEC2 = 284,
- VEC3 = 285,
- VEC4 = 286,
- CENTROID = 287,
- IN_TOK = 288,
- OUT_TOK = 289,
- INOUT_TOK = 290,
- UNIFORM = 291,
- VARYING = 292,
- NOPERSPECTIVE = 293,
- FLAT = 294,
- SMOOTH = 295,
- MAT2X2 = 296,
- MAT2X3 = 297,
- MAT2X4 = 298,
- MAT3X2 = 299,
- MAT3X3 = 300,
- MAT3X4 = 301,
- MAT4X2 = 302,
- MAT4X3 = 303,
- MAT4X4 = 304,
- SAMPLER1D = 305,
- SAMPLER2D = 306,
- SAMPLER3D = 307,
- SAMPLERCUBE = 308,
- SAMPLER1DSHADOW = 309,
- SAMPLER2DSHADOW = 310,
- SAMPLERCUBESHADOW = 311,
- SAMPLER1DARRAY = 312,
- SAMPLER2DARRAY = 313,
- SAMPLER1DARRAYSHADOW = 314,
- SAMPLER2DARRAYSHADOW = 315,
- ISAMPLER1D = 316,
- ISAMPLER2D = 317,
- ISAMPLER3D = 318,
- ISAMPLERCUBE = 319,
- ISAMPLER1DARRAY = 320,
- ISAMPLER2DARRAY = 321,
- USAMPLER1D = 322,
- USAMPLER2D = 323,
- USAMPLER3D = 324,
- USAMPLERCUBE = 325,
- USAMPLER1DARRAY = 326,
- USAMPLER2DARRAY = 327,
- STRUCT = 328,
- VOID_TOK = 329,
- WHILE = 330,
- IDENTIFIER = 331,
- FLOATCONSTANT = 332,
- INTCONSTANT = 333,
- UINTCONSTANT = 334,
- BOOLCONSTANT = 335,
- FIELD_SELECTION = 336,
- LEFT_OP = 337,
- RIGHT_OP = 338,
- INC_OP = 339,
- DEC_OP = 340,
- LE_OP = 341,
- GE_OP = 342,
- EQ_OP = 343,
- NE_OP = 344,
- AND_OP = 345,
- OR_OP = 346,
- XOR_OP = 347,
- MUL_ASSIGN = 348,
- DIV_ASSIGN = 349,
- ADD_ASSIGN = 350,
- MOD_ASSIGN = 351,
- LEFT_ASSIGN = 352,
- RIGHT_ASSIGN = 353,
- AND_ASSIGN = 354,
- XOR_ASSIGN = 355,
- OR_ASSIGN = 356,
- SUB_ASSIGN = 357,
- INVARIANT = 358,
- LOWP = 359,
- MEDIUMP = 360,
- HIGHP = 361,
- SUPERP = 362,
- PRECISION = 363,
- VERSION = 364,
- EXTENSION = 365,
- LINE = 366,
- COLON = 367,
- EOL = 368,
- INTERFACE = 369,
- OUTPUT = 370,
- PRAGMA_DEBUG_ON = 371,
- PRAGMA_DEBUG_OFF = 372,
- PRAGMA_OPTIMIZE_ON = 373,
- PRAGMA_OPTIMIZE_OFF = 374,
- PRAGMA_INVARIANT_ALL = 375,
- LAYOUT_TOK = 376,
- ASM = 377,
- CLASS = 378,
- UNION = 379,
- ENUM = 380,
- TYPEDEF = 381,
- TEMPLATE = 382,
- THIS = 383,
- PACKED_TOK = 384,
- GOTO = 385,
- INLINE_TOK = 386,
- NOINLINE = 387,
- VOLATILE = 388,
- PUBLIC_TOK = 389,
- STATIC = 390,
- EXTERN = 391,
- EXTERNAL = 392,
- LONG_TOK = 393,
- SHORT_TOK = 394,
- DOUBLE_TOK = 395,
- HALF = 396,
- FIXED_TOK = 397,
- UNSIGNED = 398,
- INPUT_TOK = 399,
- OUPTUT = 400,
- HVEC2 = 401,
- HVEC3 = 402,
- HVEC4 = 403,
- DVEC2 = 404,
- DVEC3 = 405,
- DVEC4 = 406,
- FVEC2 = 407,
- FVEC3 = 408,
- FVEC4 = 409,
- SAMPLER2DRECT = 410,
- SAMPLER3DRECT = 411,
- SAMPLER2DRECTSHADOW = 412,
- SIZEOF = 413,
- CAST = 414,
- NAMESPACE = 415,
- USING = 416,
- ERROR_TOK = 417,
- COMMON = 418,
- PARTITION = 419,
- ACTIVE = 420,
- SAMPLERBUFFER = 421,
- FILTER = 422,
- IMAGE1D = 423,
- IMAGE2D = 424,
- IMAGE3D = 425,
- IMAGECUBE = 426,
- IMAGE1DARRAY = 427,
- IMAGE2DARRAY = 428,
- IIMAGE1D = 429,
- IIMAGE2D = 430,
- IIMAGE3D = 431,
- IIMAGECUBE = 432,
- IIMAGE1DARRAY = 433,
- IIMAGE2DARRAY = 434,
- UIMAGE1D = 435,
- UIMAGE2D = 436,
- UIMAGE3D = 437,
- UIMAGECUBE = 438,
- UIMAGE1DARRAY = 439,
- UIMAGE2DARRAY = 440,
- IMAGE1DSHADOW = 441,
- IMAGE2DSHADOW = 442,
- IMAGEBUFFER = 443,
- IIMAGEBUFFER = 444,
- UIMAGEBUFFER = 445,
- IMAGE1DARRAYSHADOW = 446,
- IMAGE2DARRAYSHADOW = 447,
- ROW_MAJOR = 448
- };
-#endif
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 1676 of yacc.c */
-#line 52 "glsl_parser.ypp"
-
- int n;
- float real;
- char *identifier;
-
- struct ast_type_qualifier type_qualifier;
-
- ast_node *node;
- ast_type_specifier *type_specifier;
- ast_fully_specified_type *fully_specified_type;
- ast_function *function;
- ast_parameter_declarator *parameter_declarator;
- ast_function_definition *function_definition;
- ast_compound_statement *compound_statement;
- ast_expression *expression;
- ast_declarator_list *declarator_list;
- ast_struct_specifier *struct_specifier;
- ast_declaration *declaration;
-
- struct {
- ast_node *cond;
- ast_expression *rest;
- } for_rest_statement;
-
- struct {
- ast_node *then_statement;
- ast_node *else_statement;
- } selection_rest_statement;
-
-
-
-/* Line 1676 of yacc.c */
-#line 277 "glsl_parser.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-
+/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ATTRIBUTE = 258, + CONST_TOK = 259, + BOOL_TOK = 260, + FLOAT_TOK = 261, + INT_TOK = 262, + UINT_TOK = 263, + BREAK = 264, + CONTINUE = 265, + DO = 266, + ELSE = 267, + FOR = 268, + IF = 269, + DISCARD = 270, + RETURN = 271, + SWITCH = 272, + CASE = 273, + DEFAULT = 274, + BVEC2 = 275, + BVEC3 = 276, + BVEC4 = 277, + IVEC2 = 278, + IVEC3 = 279, + IVEC4 = 280, + UVEC2 = 281, + UVEC3 = 282, + UVEC4 = 283, + VEC2 = 284, + VEC3 = 285, + VEC4 = 286, + CENTROID = 287, + IN_TOK = 288, + OUT_TOK = 289, + INOUT_TOK = 290, + UNIFORM = 291, + VARYING = 292, + NOPERSPECTIVE = 293, + FLAT = 294, + SMOOTH = 295, + MAT2X2 = 296, + MAT2X3 = 297, + MAT2X4 = 298, + MAT3X2 = 299, + MAT3X3 = 300, + MAT3X4 = 301, + MAT4X2 = 302, + MAT4X3 = 303, + MAT4X4 = 304, + SAMPLER1D = 305, + SAMPLER2D = 306, + SAMPLER3D = 307, + SAMPLERCUBE = 308, + SAMPLER1DSHADOW = 309, + SAMPLER2DSHADOW = 310, + SAMPLERCUBESHADOW = 311, + SAMPLER1DARRAY = 312, + SAMPLER2DARRAY = 313, + SAMPLER1DARRAYSHADOW = 314, + SAMPLER2DARRAYSHADOW = 315, + ISAMPLER1D = 316, + ISAMPLER2D = 317, + ISAMPLER3D = 318, + ISAMPLERCUBE = 319, + ISAMPLER1DARRAY = 320, + ISAMPLER2DARRAY = 321, + USAMPLER1D = 322, + USAMPLER2D = 323, + USAMPLER3D = 324, + USAMPLERCUBE = 325, + USAMPLER1DARRAY = 326, + USAMPLER2DARRAY = 327, + STRUCT = 328, + VOID_TOK = 329, + WHILE = 330, + IDENTIFIER = 331, + FLOATCONSTANT = 332, + INTCONSTANT = 333, + UINTCONSTANT = 334, + BOOLCONSTANT = 335, + FIELD_SELECTION = 336, + LEFT_OP = 337, + RIGHT_OP = 338, + INC_OP = 339, + DEC_OP = 340, + LE_OP = 341, + GE_OP = 342, + EQ_OP = 343, + NE_OP = 344, + AND_OP = 345, + OR_OP = 346, + XOR_OP = 347, + MUL_ASSIGN = 348, + DIV_ASSIGN = 349, + ADD_ASSIGN = 350, + MOD_ASSIGN = 351, + LEFT_ASSIGN = 352, + RIGHT_ASSIGN = 353, + AND_ASSIGN = 354, + XOR_ASSIGN = 355, + OR_ASSIGN = 356, + SUB_ASSIGN = 357, + INVARIANT = 358, + LOWP = 359, + MEDIUMP = 360, + HIGHP = 361, + SUPERP = 362, + PRECISION = 363, + VERSION = 364, + EXTENSION = 365, + LINE = 366, + COLON = 367, + EOL = 368, + INTERFACE = 369, + OUTPUT = 370, + PRAGMA_DEBUG_ON = 371, + PRAGMA_DEBUG_OFF = 372, + PRAGMA_OPTIMIZE_ON = 373, + PRAGMA_OPTIMIZE_OFF = 374, + PRAGMA_INVARIANT_ALL = 375, + LAYOUT_TOK = 376, + ASM = 377, + CLASS = 378, + UNION = 379, + ENUM = 380, + TYPEDEF = 381, + TEMPLATE = 382, + THIS = 383, + PACKED_TOK = 384, + GOTO = 385, + INLINE_TOK = 386, + NOINLINE = 387, + VOLATILE = 388, + PUBLIC_TOK = 389, + STATIC = 390, + EXTERN = 391, + EXTERNAL = 392, + LONG_TOK = 393, + SHORT_TOK = 394, + DOUBLE_TOK = 395, + HALF = 396, + FIXED_TOK = 397, + UNSIGNED = 398, + INPUT_TOK = 399, + OUPTUT = 400, + HVEC2 = 401, + HVEC3 = 402, + HVEC4 = 403, + DVEC2 = 404, + DVEC3 = 405, + DVEC4 = 406, + FVEC2 = 407, + FVEC3 = 408, + FVEC4 = 409, + SAMPLER2DRECT = 410, + SAMPLER3DRECT = 411, + SAMPLER2DRECTSHADOW = 412, + SIZEOF = 413, + CAST = 414, + NAMESPACE = 415, + USING = 416, + ERROR_TOK = 417, + COMMON = 418, + PARTITION = 419, + ACTIVE = 420, + SAMPLERBUFFER = 421, + FILTER = 422, + IMAGE1D = 423, + IMAGE2D = 424, + IMAGE3D = 425, + IMAGECUBE = 426, + IMAGE1DARRAY = 427, + IMAGE2DARRAY = 428, + IIMAGE1D = 429, + IIMAGE2D = 430, + IIMAGE3D = 431, + IIMAGECUBE = 432, + IIMAGE1DARRAY = 433, + IIMAGE2DARRAY = 434, + UIMAGE1D = 435, + UIMAGE2D = 436, + UIMAGE3D = 437, + UIMAGECUBE = 438, + UIMAGE1DARRAY = 439, + UIMAGE2DARRAY = 440, + IMAGE1DSHADOW = 441, + IMAGE2DSHADOW = 442, + IMAGEBUFFER = 443, + IIMAGEBUFFER = 444, + UIMAGEBUFFER = 445, + IMAGE1DARRAYSHADOW = 446, + IMAGE2DARRAYSHADOW = 447, + ROW_MAJOR = 448 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 1685 of yacc.c */ +#line 52 "glsl_parser.ypp" + + int n; + float real; + char *identifier; + + struct ast_type_qualifier type_qualifier; + + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; + + struct { + ast_node *cond; + ast_expression *rest; + } for_rest_statement; + + struct { + ast_node *then_statement; + ast_node *else_statement; + } selection_rest_statement; + + + +/* Line 1685 of yacc.c */ +#line 276 "glsl_parser.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + + diff --git a/mesalib/src/glsl/glsl_parser.ypp b/mesalib/src/glsl/glsl_parser.ypp index 37fff5186..3982167c4 100644 --- a/mesalib/src/glsl/glsl_parser.ypp +++ b/mesalib/src/glsl/glsl_parser.ypp @@ -1,1645 +1,1643 @@ -%{
-/*
- * Copyright © 2008, 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "ast.h"
-#include "glsl_parser_extras.h"
-#include "glsl_types.h"
-
-#define YYLEX_PARAM state->scanner
-
-%}
-
-%pure-parser
-%error-verbose
-
-%locations
-%initial-action {
- @$.first_line = 1;
- @$.first_column = 1;
- @$.last_line = 1;
- @$.last_column = 1;
- @$.source = 0;
-}
-
-%lex-param {void *scanner}
-%parse-param {struct _mesa_glsl_parse_state *state}
-
-%union {
- int n;
- float real;
- char *identifier;
-
- struct ast_type_qualifier type_qualifier;
-
- ast_node *node;
- ast_type_specifier *type_specifier;
- ast_fully_specified_type *fully_specified_type;
- ast_function *function;
- ast_parameter_declarator *parameter_declarator;
- ast_function_definition *function_definition;
- ast_compound_statement *compound_statement;
- ast_expression *expression;
- ast_declarator_list *declarator_list;
- ast_struct_specifier *struct_specifier;
- ast_declaration *declaration;
-
- struct {
- ast_node *cond;
- ast_expression *rest;
- } for_rest_statement;
-
- struct {
- ast_node *then_statement;
- ast_node *else_statement;
- } selection_rest_statement;
-}
-
-%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK
-%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
-%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
-%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING
-%token NOPERSPECTIVE FLAT SMOOTH
-%token MAT2X2 MAT2X3 MAT2X4
-%token MAT3X2 MAT3X3 MAT3X4
-%token MAT4X2 MAT4X3 MAT4X4
-%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
-%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW
-%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE
-%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D
-%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY
-%token STRUCT VOID_TOK WHILE
-%token <identifier> IDENTIFIER
-%token <real> FLOATCONSTANT
-%token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT
-%token <identifier> FIELD_SELECTION
-%token LEFT_OP RIGHT_OP
-%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
-%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
-%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
-%token SUB_ASSIGN
-%token INVARIANT
-%token LOWP MEDIUMP HIGHP SUPERP PRECISION
-
-%token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT
-%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF
-%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF
-%token PRAGMA_INVARIANT_ALL
-%token LAYOUT_TOK
-
- /* Reserved words that are not actually used in the grammar.
- */
-%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO
-%token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL
-%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT
-%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
-%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW
-%token SIZEOF CAST NAMESPACE USING
-
-%token ERROR_TOK
-
-%token COMMON PARTITION ACTIVE SAMPLERBUFFER FILTER
-%token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY
-%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY
-%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY
-%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
-%token IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW
-%token ROW_MAJOR
-
-%type <identifier> variable_identifier
-%type <node> statement
-%type <node> statement_list
-%type <node> simple_statement
-%type <n> precision_qualifier
-%type <type_qualifier> type_qualifier
-%type <type_qualifier> storage_qualifier
-%type <type_qualifier> interpolation_qualifier
-%type <type_qualifier> layout_qualifier
-%type <type_qualifier> layout_qualifier_id_list layout_qualifier_id
-%type <type_specifier> type_specifier
-%type <type_specifier> type_specifier_no_prec
-%type <type_specifier> type_specifier_nonarray
-%type <n> basic_type_specifier_nonarray
-%type <fully_specified_type> fully_specified_type
-%type <function> function_prototype
-%type <function> function_header
-%type <function> function_header_with_parameters
-%type <function> function_declarator
-%type <parameter_declarator> parameter_declarator
-%type <parameter_declarator> parameter_declaration
-%type <type_qualifier> parameter_qualifier
-%type <type_qualifier> parameter_type_qualifier
-%type <type_specifier> parameter_type_specifier
-%type <function_definition> function_definition
-%type <compound_statement> compound_statement_no_new_scope
-%type <compound_statement> compound_statement
-%type <node> statement_no_new_scope
-%type <node> expression_statement
-%type <expression> expression
-%type <expression> primary_expression
-%type <expression> assignment_expression
-%type <expression> conditional_expression
-%type <expression> logical_or_expression
-%type <expression> logical_xor_expression
-%type <expression> logical_and_expression
-%type <expression> inclusive_or_expression
-%type <expression> exclusive_or_expression
-%type <expression> and_expression
-%type <expression> equality_expression
-%type <expression> relational_expression
-%type <expression> shift_expression
-%type <expression> additive_expression
-%type <expression> multiplicative_expression
-%type <expression> unary_expression
-%type <expression> constant_expression
-%type <expression> integer_expression
-%type <expression> postfix_expression
-%type <expression> function_call_header_with_parameters
-%type <expression> function_call_header_no_parameters
-%type <expression> function_call_header
-%type <expression> function_call_generic
-%type <expression> function_call_or_method
-%type <expression> function_call
-%type <n> assignment_operator
-%type <n> unary_operator
-%type <expression> function_identifier
-%type <node> external_declaration
-%type <declarator_list> init_declarator_list
-%type <declarator_list> single_declaration
-%type <expression> initializer
-%type <node> declaration
-%type <node> declaration_statement
-%type <node> jump_statement
-%type <struct_specifier> struct_specifier
-%type <node> struct_declaration_list
-%type <declarator_list> struct_declaration
-%type <declaration> struct_declarator
-%type <declaration> struct_declarator_list
-%type <node> selection_statement
-%type <selection_rest_statement> selection_rest_statement
-%type <node> iteration_statement
-%type <node> condition
-%type <node> conditionopt
-%type <node> for_init_statement
-%type <for_rest_statement> for_rest_statement
-%%
-
-translation_unit:
- version_statement extension_statement_list
- {
- _mesa_glsl_initialize_types(state);
- }
- external_declaration_list
- ;
-
-version_statement:
- /* blank - no #version specified: defaults are already set */
- | VERSION INTCONSTANT EOL
- {
- switch ($2) {
- case 100:
- state->es_shader = true;
- case 110:
- case 120:
- case 130:
- /* FINISHME: Check against implementation support versions. */
- state->language_version = $2;
- state->version_string =
- talloc_asprintf(state, "GLSL%s %d.%02d",
- state->es_shader ? " ES" : "",
- state->language_version / 100,
- state->language_version % 100);
- break;
- default:
- _mesa_glsl_error(& @2, state, "Shading language version"
- "%u is not supported\n", $2);
- break;
- }
- }
- ;
-
-pragma_statement:
- PRAGMA_DEBUG_ON EOL
- | PRAGMA_DEBUG_OFF EOL
- | PRAGMA_OPTIMIZE_ON EOL
- | PRAGMA_OPTIMIZE_OFF EOL
- | PRAGMA_INVARIANT_ALL EOL
- {
- if (state->language_version < 120) {
- _mesa_glsl_warning(& @1, state,
- "pragma `invariant(all)' not supported in %s",
- state->version_string);
- } else {
- state->all_invariant = true;
- }
- }
- ;
-
-extension_statement_list:
-
- | extension_statement_list extension_statement
- ;
-
-extension_statement:
- EXTENSION IDENTIFIER COLON IDENTIFIER EOL
- {
- if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) {
- YYERROR;
- }
- }
- ;
-
-external_declaration_list:
- external_declaration
- {
- /* FINISHME: The NULL test is only required because 'precision'
- * FINISHME: statements are not yet supported.
- */
- if ($1 != NULL)
- state->translation_unit.push_tail(& $1->link);
- }
- | external_declaration_list external_declaration
- {
- /* FINISHME: The NULL test is only required because 'precision'
- * FINISHME: statements are not yet supported.
- */
- if ($2 != NULL)
- state->translation_unit.push_tail(& $2->link);
- }
- ;
-
-variable_identifier:
- IDENTIFIER
- ;
-
-primary_expression:
- variable_identifier
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.identifier = $1;
- }
- | INTCONSTANT
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.int_constant = $1;
- }
- | UINTCONSTANT
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.uint_constant = $1;
- }
- | FLOATCONSTANT
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.float_constant = $1;
- }
- | BOOLCONSTANT
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.bool_constant = $1;
- }
- | '(' expression ')'
- {
- $$ = $2;
- }
- ;
-
-postfix_expression:
- primary_expression
- | postfix_expression '[' integer_expression ']'
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL);
- $$->set_location(yylloc);
- }
- | function_call
- {
- $$ = $1;
- }
- | postfix_expression '.' IDENTIFIER
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.identifier = $3;
- }
- | postfix_expression INC_OP
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL);
- $$->set_location(yylloc);
- }
- | postfix_expression DEC_OP
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL);
- $$->set_location(yylloc);
- }
- ;
-
-integer_expression:
- expression
- ;
-
-function_call:
- function_call_or_method
- ;
-
-function_call_or_method:
- function_call_generic
- | postfix_expression '.' function_call_generic
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL);
- $$->set_location(yylloc);
- }
- ;
-
-function_call_generic:
- function_call_header_with_parameters ')'
- | function_call_header_no_parameters ')'
- ;
-
-function_call_header_no_parameters:
- function_call_header VOID_TOK
- | function_call_header
- ;
-
-function_call_header_with_parameters:
- function_call_header assignment_expression
- {
- $$ = $1;
- $$->set_location(yylloc);
- $$->expressions.push_tail(& $2->link);
- }
- | function_call_header_with_parameters ',' assignment_expression
- {
- $$ = $1;
- $$->set_location(yylloc);
- $$->expressions.push_tail(& $3->link);
- }
- ;
-
- // Grammar Note: Constructors look like functions, but lexical
- // analysis recognized most of them as keywords. They are now
- // recognized through "type_specifier".
-function_call_header:
- function_identifier '('
- ;
-
-function_identifier:
- type_specifier
- {
- void *ctx = state;
- $$ = new(ctx) ast_function_expression($1);
- $$->set_location(yylloc);
- }
- | IDENTIFIER
- {
- void *ctx = state;
- ast_expression *callee = new(ctx) ast_expression($1);
- $$ = new(ctx) ast_function_expression(callee);
- $$->set_location(yylloc);
- }
- | FIELD_SELECTION
- {
- void *ctx = state;
- ast_expression *callee = new(ctx) ast_expression($1);
- $$ = new(ctx) ast_function_expression(callee);
- $$->set_location(yylloc);
- }
- ;
-
- // Grammar Note: No traditional style type casts.
-unary_expression:
- postfix_expression
- | INC_OP unary_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL);
- $$->set_location(yylloc);
- }
- | DEC_OP unary_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL);
- $$->set_location(yylloc);
- }
- | unary_operator unary_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression($1, $2, NULL, NULL);
- $$->set_location(yylloc);
- }
- ;
-
- // Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
-unary_operator:
- '+' { $$ = ast_plus; }
- | '-' { $$ = ast_neg; }
- | '!' { $$ = ast_logic_not; }
- | '~' { $$ = ast_bit_not; }
- ;
-
-multiplicative_expression:
- unary_expression
- | multiplicative_expression '*' unary_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3);
- $$->set_location(yylloc);
- }
- | multiplicative_expression '/' unary_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_div, $1, $3);
- $$->set_location(yylloc);
- }
- | multiplicative_expression '%' unary_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-additive_expression:
- multiplicative_expression
- | additive_expression '+' multiplicative_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_add, $1, $3);
- $$->set_location(yylloc);
- }
- | additive_expression '-' multiplicative_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-shift_expression:
- additive_expression
- | shift_expression LEFT_OP additive_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3);
- $$->set_location(yylloc);
- }
- | shift_expression RIGHT_OP additive_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-relational_expression:
- shift_expression
- | relational_expression '<' shift_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_less, $1, $3);
- $$->set_location(yylloc);
- }
- | relational_expression '>' shift_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3);
- $$->set_location(yylloc);
- }
- | relational_expression LE_OP shift_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3);
- $$->set_location(yylloc);
- }
- | relational_expression GE_OP shift_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-equality_expression:
- relational_expression
- | equality_expression EQ_OP relational_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3);
- $$->set_location(yylloc);
- }
- | equality_expression NE_OP relational_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-and_expression:
- equality_expression
- | and_expression '&' equality_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-exclusive_or_expression:
- and_expression
- | exclusive_or_expression '^' and_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-inclusive_or_expression:
- exclusive_or_expression
- | inclusive_or_expression '|' exclusive_or_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-logical_and_expression:
- inclusive_or_expression
- | logical_and_expression AND_OP inclusive_or_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-logical_xor_expression:
- logical_and_expression
- | logical_xor_expression XOR_OP logical_and_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-logical_or_expression:
- logical_xor_expression
- | logical_or_expression OR_OP logical_xor_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-conditional_expression:
- logical_or_expression
- | logical_or_expression '?' expression ':' assignment_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5);
- $$->set_location(yylloc);
- }
- ;
-
-assignment_expression:
- conditional_expression
- | unary_expression assignment_operator assignment_expression
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression($2, $1, $3, NULL);
- $$->set_location(yylloc);
- }
- ;
-
-assignment_operator:
- '=' { $$ = ast_assign; }
- | MUL_ASSIGN { $$ = ast_mul_assign; }
- | DIV_ASSIGN { $$ = ast_div_assign; }
- | MOD_ASSIGN { $$ = ast_mod_assign; }
- | ADD_ASSIGN { $$ = ast_add_assign; }
- | SUB_ASSIGN { $$ = ast_sub_assign; }
- | LEFT_ASSIGN { $$ = ast_ls_assign; }
- | RIGHT_ASSIGN { $$ = ast_rs_assign; }
- | AND_ASSIGN { $$ = ast_and_assign; }
- | XOR_ASSIGN { $$ = ast_xor_assign; }
- | OR_ASSIGN { $$ = ast_or_assign; }
- ;
-
-expression:
- assignment_expression
- {
- $$ = $1;
- }
- | expression ',' assignment_expression
- {
- void *ctx = state;
- if ($1->oper != ast_sequence) {
- $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->expressions.push_tail(& $1->link);
- } else {
- $$ = $1;
- }
-
- $$->expressions.push_tail(& $3->link);
- }
- ;
-
-constant_expression:
- conditional_expression
- ;
-
-declaration:
- function_prototype ';'
- {
- $$ = $1;
- }
- | init_declarator_list ';'
- {
- $$ = $1;
- }
- | PRECISION precision_qualifier type_specifier_no_prec ';'
- {
- if (($3->type_specifier != ast_float)
- && ($3->type_specifier != ast_int)) {
- _mesa_glsl_error(& @3, state, "global precision qualifier can "
- "only be applied to `int' or `float'\n");
- YYERROR;
- }
-
- $$ = NULL; /* FINISHME */
- }
- ;
-
-function_prototype:
- function_declarator ')'
- ;
-
-function_declarator:
- function_header
- | function_header_with_parameters
- ;
-
-function_header_with_parameters:
- function_header parameter_declaration
- {
- $$ = $1;
- $$->parameters.push_tail(& $2->link);
- }
- | function_header_with_parameters ',' parameter_declaration
- {
- $$ = $1;
- $$->parameters.push_tail(& $3->link);
- }
- ;
-
-function_header:
- fully_specified_type IDENTIFIER '('
- {
- void *ctx = state;
- $$ = new(ctx) ast_function();
- $$->set_location(yylloc);
- $$->return_type = $1;
- $$->identifier = $2;
- }
- ;
-
-parameter_declarator:
- type_specifier IDENTIFIER
- {
- void *ctx = state;
- $$ = new(ctx) ast_parameter_declarator();
- $$->set_location(yylloc);
- $$->type = new(ctx) ast_fully_specified_type();
- $$->type->set_location(yylloc);
- $$->type->specifier = $1;
- $$->identifier = $2;
- }
- | type_specifier IDENTIFIER '[' constant_expression ']'
- {
- void *ctx = state;
- $$ = new(ctx) ast_parameter_declarator();
- $$->set_location(yylloc);
- $$->type = new(ctx) ast_fully_specified_type();
- $$->type->set_location(yylloc);
- $$->type->specifier = $1;
- $$->identifier = $2;
- $$->is_array = true;
- $$->array_size = $4;
- }
- ;
-
-parameter_declaration:
- parameter_type_qualifier parameter_qualifier parameter_declarator
- {
- $1.flags.i |= $2.flags.i;
-
- $$ = $3;
- $$->type->qualifier = $1;
- }
- | parameter_qualifier parameter_declarator
- {
- $$ = $2;
- $$->type->qualifier = $1;
- }
- | parameter_type_qualifier parameter_qualifier parameter_type_specifier
- {
- void *ctx = state;
- $1.flags.i |= $2.flags.i;
-
- $$ = new(ctx) ast_parameter_declarator();
- $$->set_location(yylloc);
- $$->type = new(ctx) ast_fully_specified_type();
- $$->type->qualifier = $1;
- $$->type->specifier = $3;
- }
- | parameter_qualifier parameter_type_specifier
- {
- void *ctx = state;
- $$ = new(ctx) ast_parameter_declarator();
- $$->set_location(yylloc);
- $$->type = new(ctx) ast_fully_specified_type();
- $$->type->qualifier = $1;
- $$->type->specifier = $2;
- }
- ;
-
-parameter_qualifier:
- /* empty */
- {
- memset(& $$, 0, sizeof($$));
- }
- | IN_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.in = 1;
- }
- | OUT_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.out = 1;
- }
- | INOUT_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.in = 1;
- $$.flags.q.out = 1;
- }
- ;
-
-parameter_type_specifier:
- type_specifier
- ;
-
-init_declarator_list:
- single_declaration
- | init_declarator_list ',' IDENTIFIER
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL);
- decl->set_location(yylloc);
-
- $$ = $1;
- $$->declarations.push_tail(&decl->link);
- }
- | init_declarator_list ',' IDENTIFIER '[' ']'
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL);
- decl->set_location(yylloc);
-
- $$ = $1;
- $$->declarations.push_tail(&decl->link);
- }
- | init_declarator_list ',' IDENTIFIER '[' constant_expression ']'
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL);
- decl->set_location(yylloc);
-
- $$ = $1;
- $$->declarations.push_tail(&decl->link);
- }
- | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7);
- decl->set_location(yylloc);
-
- $$ = $1;
- $$->declarations.push_tail(&decl->link);
- }
- | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8);
- decl->set_location(yylloc);
-
- $$ = $1;
- $$->declarations.push_tail(&decl->link);
- }
- | init_declarator_list ',' IDENTIFIER '=' initializer
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5);
- decl->set_location(yylloc);
-
- $$ = $1;
- $$->declarations.push_tail(&decl->link);
- }
- ;
-
- // Grammar Note: No 'enum', or 'typedef'.
-single_declaration:
- fully_specified_type
- {
- void *ctx = state;
- if ($1->specifier->type_specifier != ast_struct) {
- _mesa_glsl_error(& @1, state, "empty declaration list\n");
- YYERROR;
- } else {
- $$ = new(ctx) ast_declarator_list($1);
- $$->set_location(yylloc);
- }
- }
- | fully_specified_type IDENTIFIER
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
-
- $$ = new(ctx) ast_declarator_list($1);
- $$->set_location(yylloc);
- $$->declarations.push_tail(&decl->link);
- }
- | fully_specified_type IDENTIFIER '[' ']'
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL);
-
- $$ = new(ctx) ast_declarator_list($1);
- $$->set_location(yylloc);
- $$->declarations.push_tail(&decl->link);
- }
- | fully_specified_type IDENTIFIER '[' constant_expression ']'
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL);
-
- $$ = new(ctx) ast_declarator_list($1);
- $$->set_location(yylloc);
- $$->declarations.push_tail(&decl->link);
- }
- | fully_specified_type IDENTIFIER '[' ']' '=' initializer
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6);
-
- $$ = new(ctx) ast_declarator_list($1);
- $$->set_location(yylloc);
- $$->declarations.push_tail(&decl->link);
- }
- | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7);
-
- $$ = new(ctx) ast_declarator_list($1);
- $$->set_location(yylloc);
- $$->declarations.push_tail(&decl->link);
- }
- | fully_specified_type IDENTIFIER '=' initializer
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4);
-
- $$ = new(ctx) ast_declarator_list($1);
- $$->set_location(yylloc);
- $$->declarations.push_tail(&decl->link);
- }
- | INVARIANT IDENTIFIER // Vertex only.
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
-
- $$ = new(ctx) ast_declarator_list(NULL);
- $$->set_location(yylloc);
- $$->invariant = true;
-
- $$->declarations.push_tail(&decl->link);
- }
- ;
-
-fully_specified_type:
- type_specifier
- {
- void *ctx = state;
- $$ = new(ctx) ast_fully_specified_type();
- $$->set_location(yylloc);
- $$->specifier = $1;
- }
- | type_qualifier type_specifier
- {
- void *ctx = state;
- $$ = new(ctx) ast_fully_specified_type();
- $$->set_location(yylloc);
- $$->qualifier = $1;
- $$->specifier = $2;
- }
- ;
-
-layout_qualifier:
- LAYOUT_TOK '(' layout_qualifier_id_list ')'
- {
- $$ = $3;
- }
- ;
-
-layout_qualifier_id_list:
- layout_qualifier_id
- | layout_qualifier_id_list ',' layout_qualifier_id
- {
- if (($1.flags.i & $3.flags.i) != 0) {
- _mesa_glsl_error(& @3, state,
- "duplicate layout qualifiers used\n");
- YYERROR;
- }
-
- $$.flags.i = $1.flags.i | $3.flags.i;
-
- if ($1.flags.q.explicit_location)
- $$.location = $1.location;
-
- if ($3.flags.q.explicit_location)
- $$.location = $3.location;
- }
- ;
-
-layout_qualifier_id:
- IDENTIFIER
- {
- bool got_one = false;
-
- memset(& $$, 0, sizeof($$));
-
- if (state->ARB_fragment_coord_conventions_enable) {
- if (strcmp($1, "origin_upper_left") == 0) {
- got_one = true;
- $$.flags.q.origin_upper_left = 1;
- } else if (strcmp($1, "pixel_center_integer") == 0) {
- got_one = true;
- $$.flags.q.pixel_center_integer = 1;
- }
- }
-
- /* If the identifier didn't match any known layout identifiers,
- * emit an error.
- */
- if (!got_one) {
- _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
- "`%s'\n", $1);
- YYERROR;
- } else if (state->ARB_fragment_coord_conventions_warn) {
- _mesa_glsl_warning(& @1, state,
- "GL_ARB_fragment_coord_conventions layout "
- "identifier `%s' used\n", $1);
- }
- }
- | IDENTIFIER '=' INTCONSTANT
- {
- bool got_one = false;
-
- memset(& $$, 0, sizeof($$));
-
- if (state->ARB_explicit_attrib_location_enable) {
- /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
- * FINISHME: GLSL 1.30 (or later) are supported.
- */
- if (strcmp("location", $1) == 0) {
- got_one = true;
-
- $$.flags.q.explicit_location = 1;
-
- if ($3 >= 0) {
- $$.location = $3;
- } else {
- _mesa_glsl_error(& @3, state,
- "invalid location %d specified\n", $3);
- YYERROR;
- }
- }
- }
-
- /* If the identifier didn't match any known layout identifiers,
- * emit an error.
- */
- if (!got_one) {
- _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
- "`%s'\n", $1);
- YYERROR;
- } else if (state->ARB_explicit_attrib_location_warn) {
- _mesa_glsl_warning(& @1, state,
- "GL_ARB_explicit_attrib_location layout "
- "identifier `%s' used\n", $1);
- }
- }
- ;
-
-interpolation_qualifier:
- SMOOTH
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.smooth = 1;
- }
- | FLAT
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.flat = 1;
- }
- | NOPERSPECTIVE
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.noperspective = 1;
- }
- ;
-
-parameter_type_qualifier:
- CONST_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.constant = 1;
- }
- ;
-
-type_qualifier:
- storage_qualifier
- | layout_qualifier
- | layout_qualifier storage_qualifier
- {
- $$ = $1;
- $$.flags.i |= $2.flags.i;
- }
- | interpolation_qualifier
- | interpolation_qualifier storage_qualifier
- {
- $$ = $1;
- $$.flags.i |= $2.flags.i;
- }
- | INVARIANT storage_qualifier
- {
- $$ = $2;
- $$.flags.q.invariant = 1;
- }
- | INVARIANT interpolation_qualifier storage_qualifier
- {
- $$ = $2;
- $$.flags.i |= $3.flags.i;
- $$.flags.q.invariant = 1;
- }
- | INVARIANT
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.invariant = 1;
- }
- ;
-
-storage_qualifier:
- CONST_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.constant = 1;
- }
- | ATTRIBUTE
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.attribute = 1;
- }
- | VARYING
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.varying = 1;
- }
- | CENTROID VARYING
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.centroid = 1;
- $$.flags.q.varying = 1;
- }
- | IN_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.in = 1;
- }
- | OUT_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.out = 1;
- }
- | CENTROID IN_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.centroid = 1; $$.flags.q.in = 1;
- }
- | CENTROID OUT_TOK
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.centroid = 1; $$.flags.q.out = 1;
- }
- | UNIFORM
- {
- memset(& $$, 0, sizeof($$));
- $$.flags.q.uniform = 1;
- }
- ;
-
-type_specifier:
- type_specifier_no_prec
- | precision_qualifier type_specifier_no_prec
- {
- $$ = $2;
- $$->precision = $1;
- }
- ;
-
-type_specifier_no_prec:
- type_specifier_nonarray
- | type_specifier_nonarray '[' ']'
- {
- $$ = $1;
- $$->is_array = true;
- $$->array_size = NULL;
- }
- | type_specifier_nonarray '[' constant_expression ']'
- {
- $$ = $1;
- $$->is_array = true;
- $$->array_size = $3;
- }
- ;
-
-type_specifier_nonarray:
- basic_type_specifier_nonarray
- {
- void *ctx = state;
- $$ = new(ctx) ast_type_specifier($1);
- $$->set_location(yylloc);
- }
- | struct_specifier
- {
- void *ctx = state;
- $$ = new(ctx) ast_type_specifier($1);
- $$->set_location(yylloc);
- }
- | IDENTIFIER
- {
- void *ctx = state;
- $$ = new(ctx) ast_type_specifier($1);
- $$->set_location(yylloc);
- }
- ;
-
-basic_type_specifier_nonarray:
- VOID_TOK { $$ = ast_void; }
- | FLOAT_TOK { $$ = ast_float; }
- | INT_TOK { $$ = ast_int; }
- | UINT_TOK { $$ = ast_uint; }
- | BOOL_TOK { $$ = ast_bool; }
- | VEC2 { $$ = ast_vec2; }
- | VEC3 { $$ = ast_vec3; }
- | VEC4 { $$ = ast_vec4; }
- | BVEC2 { $$ = ast_bvec2; }
- | BVEC3 { $$ = ast_bvec3; }
- | BVEC4 { $$ = ast_bvec4; }
- | IVEC2 { $$ = ast_ivec2; }
- | IVEC3 { $$ = ast_ivec3; }
- | IVEC4 { $$ = ast_ivec4; }
- | UVEC2 { $$ = ast_uvec2; }
- | UVEC3 { $$ = ast_uvec3; }
- | UVEC4 { $$ = ast_uvec4; }
- | MAT2X2 { $$ = ast_mat2; }
- | MAT2X3 { $$ = ast_mat2x3; }
- | MAT2X4 { $$ = ast_mat2x4; }
- | MAT3X2 { $$ = ast_mat3x2; }
- | MAT3X3 { $$ = ast_mat3; }
- | MAT3X4 { $$ = ast_mat3x4; }
- | MAT4X2 { $$ = ast_mat4x2; }
- | MAT4X3 { $$ = ast_mat4x3; }
- | MAT4X4 { $$ = ast_mat4; }
- | SAMPLER1D { $$ = ast_sampler1d; }
- | SAMPLER2D { $$ = ast_sampler2d; }
- | SAMPLER2DRECT { $$ = ast_sampler2drect; }
- | SAMPLER3D { $$ = ast_sampler3d; }
- | SAMPLERCUBE { $$ = ast_samplercube; }
- | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; }
- | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; }
- | SAMPLER2DRECTSHADOW { $$ = ast_sampler2drectshadow; }
- | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; }
- | SAMPLER1DARRAY { $$ = ast_sampler1darray; }
- | SAMPLER2DARRAY { $$ = ast_sampler2darray; }
- | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; }
- | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; }
- | ISAMPLER1D { $$ = ast_isampler1d; }
- | ISAMPLER2D { $$ = ast_isampler2d; }
- | ISAMPLER3D { $$ = ast_isampler3d; }
- | ISAMPLERCUBE { $$ = ast_isamplercube; }
- | ISAMPLER1DARRAY { $$ = ast_isampler1darray; }
- | ISAMPLER2DARRAY { $$ = ast_isampler2darray; }
- | USAMPLER1D { $$ = ast_usampler1d; }
- | USAMPLER2D { $$ = ast_usampler2d; }
- | USAMPLER3D { $$ = ast_usampler3d; }
- | USAMPLERCUBE { $$ = ast_usamplercube; }
- | USAMPLER1DARRAY { $$ = ast_usampler1darray; }
- | USAMPLER2DARRAY { $$ = ast_usampler2darray; }
- ;
-
-precision_qualifier:
- HIGHP {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
-
- $$ = ast_precision_high;
- }
- | MEDIUMP {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
-
- $$ = ast_precision_medium;
- }
- | LOWP {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
-
- $$ = ast_precision_low;
- }
- ;
-
-struct_specifier:
- STRUCT IDENTIFIER '{' struct_declaration_list '}'
- {
- void *ctx = state;
- $$ = new(ctx) ast_struct_specifier($2, $4);
- $$->set_location(yylloc);
- }
- | STRUCT '{' struct_declaration_list '}'
- {
- void *ctx = state;
- $$ = new(ctx) ast_struct_specifier(NULL, $3);
- $$->set_location(yylloc);
- }
- ;
-
-struct_declaration_list:
- struct_declaration
- {
- $$ = (ast_node *) $1;
- $1->link.self_link();
- }
- | struct_declaration_list struct_declaration
- {
- $$ = (ast_node *) $1;
- $$->link.insert_before(& $2->link);
- }
- ;
-
-struct_declaration:
- type_specifier struct_declarator_list ';'
- {
- void *ctx = state;
- ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
- type->set_location(yylloc);
-
- type->specifier = $1;
- $$ = new(ctx) ast_declarator_list(type);
- $$->set_location(yylloc);
-
- $$->declarations.push_degenerate_list_at_head(& $2->link);
- }
- ;
-
-struct_declarator_list:
- struct_declarator
- {
- $$ = $1;
- $1->link.self_link();
- }
- | struct_declarator_list ',' struct_declarator
- {
- $$ = $1;
- $$->link.insert_before(& $3->link);
- }
- ;
-
-struct_declarator:
- IDENTIFIER
- {
- void *ctx = state;
- $$ = new(ctx) ast_declaration($1, false, NULL, NULL);
- $$->set_location(yylloc);
- }
- | IDENTIFIER '[' constant_expression ']'
- {
- void *ctx = state;
- $$ = new(ctx) ast_declaration($1, true, $3, NULL);
- $$->set_location(yylloc);
- }
- ;
-
-initializer:
- assignment_expression
- ;
-
-declaration_statement:
- declaration
- ;
-
- // Grammar Note: labeled statements for SWITCH only; 'goto' is not
- // supported.
-statement:
- compound_statement { $$ = (ast_node *) $1; }
- | simple_statement
- ;
-
-simple_statement:
- declaration_statement
- | expression_statement
- | selection_statement
- | switch_statement { $$ = NULL; }
- | case_label { $$ = NULL; }
- | iteration_statement
- | jump_statement
- ;
-
-compound_statement:
- '{' '}'
- {
- void *ctx = state;
- $$ = new(ctx) ast_compound_statement(true, NULL);
- $$->set_location(yylloc);
- }
- | '{' statement_list '}'
- {
- void *ctx = state;
- $$ = new(ctx) ast_compound_statement(true, $2);
- $$->set_location(yylloc);
- }
- ;
-
-statement_no_new_scope:
- compound_statement_no_new_scope { $$ = (ast_node *) $1; }
- | simple_statement
- ;
-
-compound_statement_no_new_scope:
- '{' '}'
- {
- void *ctx = state;
- $$ = new(ctx) ast_compound_statement(false, NULL);
- $$->set_location(yylloc);
- }
- | '{' statement_list '}'
- {
- void *ctx = state;
- $$ = new(ctx) ast_compound_statement(false, $2);
- $$->set_location(yylloc);
- }
- ;
-
-statement_list:
- statement
- {
- if ($1 == NULL) {
- _mesa_glsl_error(& @1, state, "<nil> statement\n");
- assert($1 != NULL);
- }
-
- $$ = $1;
- $$->link.self_link();
- }
- | statement_list statement
- {
- if ($2 == NULL) {
- _mesa_glsl_error(& @2, state, "<nil> statement\n");
- assert($2 != NULL);
- }
- $$ = $1;
- $$->link.insert_before(& $2->link);
- }
- ;
-
-expression_statement:
- ';'
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_statement(NULL);
- $$->set_location(yylloc);
- }
- | expression ';'
- {
- void *ctx = state;
- $$ = new(ctx) ast_expression_statement($1);
- $$->set_location(yylloc);
- }
- ;
-
-selection_statement:
- IF '(' expression ')' selection_rest_statement
- {
- $$ = new(state) ast_selection_statement($3, $5.then_statement,
- $5.else_statement);
- $$->set_location(yylloc);
- }
- ;
-
-selection_rest_statement:
- statement ELSE statement
- {
- $$.then_statement = $1;
- $$.else_statement = $3;
- }
- | statement
- {
- $$.then_statement = $1;
- $$.else_statement = NULL;
- }
- ;
-
-condition:
- expression
- {
- $$ = (ast_node *) $1;
- }
- | fully_specified_type IDENTIFIER '=' initializer
- {
- void *ctx = state;
- ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4);
- ast_declarator_list *declarator = new(ctx) ast_declarator_list($1);
- decl->set_location(yylloc);
- declarator->set_location(yylloc);
-
- declarator->declarations.push_tail(&decl->link);
- $$ = declarator;
- }
- ;
-
-switch_statement:
- SWITCH '(' expression ')' compound_statement
- ;
-
-case_label:
- CASE expression ':'
- | DEFAULT ':'
- ;
-
-iteration_statement:
- WHILE '(' condition ')' statement_no_new_scope
- {
- void *ctx = state;
- $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while,
- NULL, $3, NULL, $5);
- $$->set_location(yylloc);
- }
- | DO statement WHILE '(' expression ')' ';'
- {
- void *ctx = state;
- $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while,
- NULL, $5, NULL, $2);
- $$->set_location(yylloc);
- }
- | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope
- {
- void *ctx = state;
- $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for,
- $3, $4.cond, $4.rest, $6);
- $$->set_location(yylloc);
- }
- ;
-
-for_init_statement:
- expression_statement
- | declaration_statement
- ;
-
-conditionopt:
- condition
- | /* empty */
- {
- $$ = NULL;
- }
- ;
-
-for_rest_statement:
- conditionopt ';'
- {
- $$.cond = $1;
- $$.rest = NULL;
- }
- | conditionopt ';' expression
- {
- $$.cond = $1;
- $$.rest = $3;
- }
- ;
-
- // Grammar Note: No 'goto'. Gotos are not supported.
-jump_statement:
- CONTINUE ';'
- {
- void *ctx = state;
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL);
- $$->set_location(yylloc);
- }
- | BREAK ';'
- {
- void *ctx = state;
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL);
- $$->set_location(yylloc);
- }
- | RETURN ';'
- {
- void *ctx = state;
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL);
- $$->set_location(yylloc);
- }
- | RETURN expression ';'
- {
- void *ctx = state;
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2);
- $$->set_location(yylloc);
- }
- | DISCARD ';' // Fragment shader only.
- {
- void *ctx = state;
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL);
- $$->set_location(yylloc);
- }
- ;
-
-external_declaration:
- function_definition { $$ = $1; }
- | declaration { $$ = $1; }
- | pragma_statement { $$ = NULL; }
- ;
-
-function_definition:
- function_prototype compound_statement_no_new_scope
- {
- void *ctx = state;
- $$ = new(ctx) ast_function_definition();
- $$->set_location(yylloc);
- $$->prototype = $1;
- $$->body = $2;
- }
- ;
+%{ +/* + * Copyright © 2008, 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_types.h" + +#define YYLEX_PARAM state->scanner + +%} + +%pure-parser +%error-verbose + +%locations +%initial-action { + @$.first_line = 1; + @$.first_column = 1; + @$.last_line = 1; + @$.last_column = 1; + @$.source = 0; +} + +%lex-param {void *scanner} +%parse-param {struct _mesa_glsl_parse_state *state} + +%union { + int n; + float real; + char *identifier; + + struct ast_type_qualifier type_qualifier; + + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; + + struct { + ast_node *cond; + ast_expression *rest; + } for_rest_statement; + + struct { + ast_node *then_statement; + ast_node *else_statement; + } selection_rest_statement; +} + +%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK +%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 +%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING +%token NOPERSPECTIVE FLAT SMOOTH +%token MAT2X2 MAT2X3 MAT2X4 +%token MAT3X2 MAT3X3 MAT3X4 +%token MAT4X2 MAT4X3 MAT4X4 +%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW +%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW +%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE +%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D +%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY +%token STRUCT VOID_TOK WHILE +%token <identifier> IDENTIFIER +%token <real> FLOATCONSTANT +%token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token <identifier> FIELD_SELECTION +%token LEFT_OP RIGHT_OP +%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP +%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN +%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN +%token SUB_ASSIGN +%token INVARIANT +%token LOWP MEDIUMP HIGHP SUPERP PRECISION + +%token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT +%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF +%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF +%token PRAGMA_INVARIANT_ALL +%token LAYOUT_TOK + + /* Reserved words that are not actually used in the grammar. + */ +%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO +%token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL +%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT +%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 +%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW +%token SIZEOF CAST NAMESPACE USING + +%token ERROR_TOK + +%token COMMON PARTITION ACTIVE SAMPLERBUFFER FILTER +%token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY +%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY +%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY +%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER +%token IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW +%token ROW_MAJOR + +%type <identifier> variable_identifier +%type <node> statement +%type <node> statement_list +%type <node> simple_statement +%type <n> precision_qualifier +%type <type_qualifier> type_qualifier +%type <type_qualifier> storage_qualifier +%type <type_qualifier> interpolation_qualifier +%type <type_qualifier> layout_qualifier +%type <type_qualifier> layout_qualifier_id_list layout_qualifier_id +%type <type_specifier> type_specifier +%type <type_specifier> type_specifier_no_prec +%type <type_specifier> type_specifier_nonarray +%type <n> basic_type_specifier_nonarray +%type <fully_specified_type> fully_specified_type +%type <function> function_prototype +%type <function> function_header +%type <function> function_header_with_parameters +%type <function> function_declarator +%type <parameter_declarator> parameter_declarator +%type <parameter_declarator> parameter_declaration +%type <type_qualifier> parameter_qualifier +%type <type_qualifier> parameter_type_qualifier +%type <type_specifier> parameter_type_specifier +%type <function_definition> function_definition +%type <compound_statement> compound_statement_no_new_scope +%type <compound_statement> compound_statement +%type <node> statement_no_new_scope +%type <node> expression_statement +%type <expression> expression +%type <expression> primary_expression +%type <expression> assignment_expression +%type <expression> conditional_expression +%type <expression> logical_or_expression +%type <expression> logical_xor_expression +%type <expression> logical_and_expression +%type <expression> inclusive_or_expression +%type <expression> exclusive_or_expression +%type <expression> and_expression +%type <expression> equality_expression +%type <expression> relational_expression +%type <expression> shift_expression +%type <expression> additive_expression +%type <expression> multiplicative_expression +%type <expression> unary_expression +%type <expression> constant_expression +%type <expression> integer_expression +%type <expression> postfix_expression +%type <expression> function_call_header_with_parameters +%type <expression> function_call_header_no_parameters +%type <expression> function_call_header +%type <expression> function_call_generic +%type <expression> function_call_or_method +%type <expression> function_call +%type <n> assignment_operator +%type <n> unary_operator +%type <expression> function_identifier +%type <node> external_declaration +%type <declarator_list> init_declarator_list +%type <declarator_list> single_declaration +%type <expression> initializer +%type <node> declaration +%type <node> declaration_statement +%type <node> jump_statement +%type <struct_specifier> struct_specifier +%type <node> struct_declaration_list +%type <declarator_list> struct_declaration +%type <declaration> struct_declarator +%type <declaration> struct_declarator_list +%type <node> selection_statement +%type <selection_rest_statement> selection_rest_statement +%type <node> iteration_statement +%type <node> condition +%type <node> conditionopt +%type <node> for_init_statement +%type <for_rest_statement> for_rest_statement +%% + +translation_unit: + version_statement extension_statement_list + { + _mesa_glsl_initialize_types(state); + } + external_declaration_list + ; + +version_statement: + /* blank - no #version specified: defaults are already set */ + | VERSION INTCONSTANT EOL + { + switch ($2) { + case 100: + state->es_shader = true; + case 110: + case 120: + case 130: + /* FINISHME: Check against implementation support versions. */ + state->language_version = $2; + state->version_string = + talloc_asprintf(state, "GLSL%s %d.%02d", + state->es_shader ? " ES" : "", + state->language_version / 100, + state->language_version % 100); + break; + default: + _mesa_glsl_error(& @2, state, "Shading language version" + "%u is not supported\n", $2); + break; + } + } + ; + +pragma_statement: + PRAGMA_DEBUG_ON EOL + | PRAGMA_DEBUG_OFF EOL + | PRAGMA_OPTIMIZE_ON EOL + | PRAGMA_OPTIMIZE_OFF EOL + | PRAGMA_INVARIANT_ALL EOL + { + if (state->language_version < 120) { + _mesa_glsl_warning(& @1, state, + "pragma `invariant(all)' not supported in %s", + state->version_string); + } else { + state->all_invariant = true; + } + } + ; + +extension_statement_list: + + | extension_statement_list extension_statement + ; + +extension_statement: + EXTENSION IDENTIFIER COLON IDENTIFIER EOL + { + if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) { + YYERROR; + } + } + ; + +external_declaration_list: + external_declaration + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ($1 != NULL) + state->translation_unit.push_tail(& $1->link); + } + | external_declaration_list external_declaration + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ($2 != NULL) + state->translation_unit.push_tail(& $2->link); + } + ; + +variable_identifier: + IDENTIFIER + ; + +primary_expression: + variable_identifier + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.identifier = $1; + } + | INTCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.int_constant = $1; + } + | UINTCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.uint_constant = $1; + } + | FLOATCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.float_constant = $1; + } + | BOOLCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.bool_constant = $1; + } + | '(' expression ')' + { + $$ = $2; + } + ; + +postfix_expression: + primary_expression + | postfix_expression '[' integer_expression ']' + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); + $$->set_location(yylloc); + } + | function_call + { + $$ = $1; + } + | postfix_expression '.' IDENTIFIER + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.identifier = $3; + } + | postfix_expression INC_OP + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); + $$->set_location(yylloc); + } + | postfix_expression DEC_OP + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); + $$->set_location(yylloc); + } + ; + +integer_expression: + expression + ; + +function_call: + function_call_or_method + ; + +function_call_or_method: + function_call_generic + | postfix_expression '.' function_call_generic + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); + $$->set_location(yylloc); + } + ; + +function_call_generic: + function_call_header_with_parameters ')' + | function_call_header_no_parameters ')' + ; + +function_call_header_no_parameters: + function_call_header VOID_TOK + | function_call_header + ; + +function_call_header_with_parameters: + function_call_header assignment_expression + { + $$ = $1; + $$->set_location(yylloc); + $$->expressions.push_tail(& $2->link); + } + | function_call_header_with_parameters ',' assignment_expression + { + $$ = $1; + $$->set_location(yylloc); + $$->expressions.push_tail(& $3->link); + } + ; + + // Grammar Note: Constructors look like functions, but lexical + // analysis recognized most of them as keywords. They are now + // recognized through "type_specifier". +function_call_header: + function_identifier '(' + ; + +function_identifier: + type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_function_expression($1); + $$->set_location(yylloc); + } + | IDENTIFIER + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression($1); + $$ = new(ctx) ast_function_expression(callee); + $$->set_location(yylloc); + } + | FIELD_SELECTION + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression($1); + $$ = new(ctx) ast_function_expression(callee); + $$->set_location(yylloc); + } + ; + + // Grammar Note: No traditional style type casts. +unary_expression: + postfix_expression + | INC_OP unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); + $$->set_location(yylloc); + } + | DEC_OP unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); + $$->set_location(yylloc); + } + | unary_operator unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression($1, $2, NULL, NULL); + $$->set_location(yylloc); + } + ; + + // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. +unary_operator: + '+' { $$ = ast_plus; } + | '-' { $$ = ast_neg; } + | '!' { $$ = ast_logic_not; } + | '~' { $$ = ast_bit_not; } + ; + +multiplicative_expression: + unary_expression + | multiplicative_expression '*' unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); + $$->set_location(yylloc); + } + | multiplicative_expression '/' unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); + $$->set_location(yylloc); + } + | multiplicative_expression '%' unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); + $$->set_location(yylloc); + } + ; + +additive_expression: + multiplicative_expression + | additive_expression '+' multiplicative_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); + $$->set_location(yylloc); + } + | additive_expression '-' multiplicative_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); + $$->set_location(yylloc); + } + ; + +shift_expression: + additive_expression + | shift_expression LEFT_OP additive_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); + $$->set_location(yylloc); + } + | shift_expression RIGHT_OP additive_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); + $$->set_location(yylloc); + } + ; + +relational_expression: + shift_expression + | relational_expression '<' shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); + $$->set_location(yylloc); + } + | relational_expression '>' shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); + $$->set_location(yylloc); + } + | relational_expression LE_OP shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); + $$->set_location(yylloc); + } + | relational_expression GE_OP shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); + $$->set_location(yylloc); + } + ; + +equality_expression: + relational_expression + | equality_expression EQ_OP relational_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); + $$->set_location(yylloc); + } + | equality_expression NE_OP relational_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); + $$->set_location(yylloc); + } + ; + +and_expression: + equality_expression + | and_expression '&' equality_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3); + $$->set_location(yylloc); + } + ; + +exclusive_or_expression: + and_expression + | exclusive_or_expression '^' and_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); + $$->set_location(yylloc); + } + ; + +inclusive_or_expression: + exclusive_or_expression + | inclusive_or_expression '|' exclusive_or_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); + $$->set_location(yylloc); + } + ; + +logical_and_expression: + inclusive_or_expression + | logical_and_expression AND_OP inclusive_or_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); + $$->set_location(yylloc); + } + ; + +logical_xor_expression: + logical_and_expression + | logical_xor_expression XOR_OP logical_and_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); + $$->set_location(yylloc); + } + ; + +logical_or_expression: + logical_xor_expression + | logical_or_expression OR_OP logical_xor_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); + $$->set_location(yylloc); + } + ; + +conditional_expression: + logical_or_expression + | logical_or_expression '?' expression ':' assignment_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); + $$->set_location(yylloc); + } + ; + +assignment_expression: + conditional_expression + | unary_expression assignment_operator assignment_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression($2, $1, $3, NULL); + $$->set_location(yylloc); + } + ; + +assignment_operator: + '=' { $$ = ast_assign; } + | MUL_ASSIGN { $$ = ast_mul_assign; } + | DIV_ASSIGN { $$ = ast_div_assign; } + | MOD_ASSIGN { $$ = ast_mod_assign; } + | ADD_ASSIGN { $$ = ast_add_assign; } + | SUB_ASSIGN { $$ = ast_sub_assign; } + | LEFT_ASSIGN { $$ = ast_ls_assign; } + | RIGHT_ASSIGN { $$ = ast_rs_assign; } + | AND_ASSIGN { $$ = ast_and_assign; } + | XOR_ASSIGN { $$ = ast_xor_assign; } + | OR_ASSIGN { $$ = ast_or_assign; } + ; + +expression: + assignment_expression + { + $$ = $1; + } + | expression ',' assignment_expression + { + void *ctx = state; + if ($1->oper != ast_sequence) { + $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->expressions.push_tail(& $1->link); + } else { + $$ = $1; + } + + $$->expressions.push_tail(& $3->link); + } + ; + +constant_expression: + conditional_expression + ; + +declaration: + function_prototype ';' + { + $$ = $1; + } + | init_declarator_list ';' + { + $$ = $1; + } + | PRECISION precision_qualifier type_specifier_no_prec ';' + { + $3->precision = $2; + $3->is_precision_statement = true; + $$ = $3; + } + ; + +function_prototype: + function_declarator ')' + ; + +function_declarator: + function_header + | function_header_with_parameters + ; + +function_header_with_parameters: + function_header parameter_declaration + { + $$ = $1; + $$->parameters.push_tail(& $2->link); + } + | function_header_with_parameters ',' parameter_declaration + { + $$ = $1; + $$->parameters.push_tail(& $3->link); + } + ; + +function_header: + fully_specified_type IDENTIFIER '(' + { + void *ctx = state; + $$ = new(ctx) ast_function(); + $$->set_location(yylloc); + $$->return_type = $1; + $$->identifier = $2; + } + ; + +parameter_declarator: + type_specifier IDENTIFIER + { + void *ctx = state; + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->set_location(yylloc); + $$->type->specifier = $1; + $$->identifier = $2; + } + | type_specifier IDENTIFIER '[' constant_expression ']' + { + void *ctx = state; + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->set_location(yylloc); + $$->type->specifier = $1; + $$->identifier = $2; + $$->is_array = true; + $$->array_size = $4; + } + ; + +parameter_declaration: + parameter_type_qualifier parameter_qualifier parameter_declarator + { + $1.flags.i |= $2.flags.i; + + $$ = $3; + $$->type->qualifier = $1; + } + | parameter_qualifier parameter_declarator + { + $$ = $2; + $$->type->qualifier = $1; + } + | parameter_type_qualifier parameter_qualifier parameter_type_specifier + { + void *ctx = state; + $1.flags.i |= $2.flags.i; + + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->qualifier = $1; + $$->type->specifier = $3; + } + | parameter_qualifier parameter_type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->qualifier = $1; + $$->type->specifier = $2; + } + ; + +parameter_qualifier: + /* empty */ + { + memset(& $$, 0, sizeof($$)); + } + | IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.in = 1; + } + | OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.out = 1; + } + | INOUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.in = 1; + $$.flags.q.out = 1; + } + ; + +parameter_type_specifier: + type_specifier + ; + +init_declarator_list: + single_declaration + | init_declarator_list ',' IDENTIFIER + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + } + | init_declarator_list ',' IDENTIFIER '[' ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + } + | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + } + | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + } + | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + } + | init_declarator_list ',' IDENTIFIER '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + } + ; + + // Grammar Note: No 'enum', or 'typedef'. +single_declaration: + fully_specified_type + { + void *ctx = state; + if ($1->specifier->type_specifier != ast_struct) { + _mesa_glsl_error(& @1, state, "empty declaration list\n"); + YYERROR; + } else { + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + } + } + | fully_specified_type IDENTIFIER + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type IDENTIFIER '[' ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type IDENTIFIER '[' constant_expression ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type IDENTIFIER '[' ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type IDENTIFIER '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | INVARIANT IDENTIFIER // Vertex only. + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); + + $$ = new(ctx) ast_declarator_list(NULL); + $$->set_location(yylloc); + $$->invariant = true; + + $$->declarations.push_tail(&decl->link); + } + ; + +fully_specified_type: + type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_fully_specified_type(); + $$->set_location(yylloc); + $$->specifier = $1; + } + | type_qualifier type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_fully_specified_type(); + $$->set_location(yylloc); + $$->qualifier = $1; + $$->specifier = $2; + } + ; + +layout_qualifier: + LAYOUT_TOK '(' layout_qualifier_id_list ')' + { + $$ = $3; + } + ; + +layout_qualifier_id_list: + layout_qualifier_id + | layout_qualifier_id_list ',' layout_qualifier_id + { + if (($1.flags.i & $3.flags.i) != 0) { + _mesa_glsl_error(& @3, state, + "duplicate layout qualifiers used\n"); + YYERROR; + } + + $$.flags.i = $1.flags.i | $3.flags.i; + + if ($1.flags.q.explicit_location) + $$.location = $1.location; + + if ($3.flags.q.explicit_location) + $$.location = $3.location; + } + ; + +layout_qualifier_id: + IDENTIFIER + { + bool got_one = false; + + memset(& $$, 0, sizeof($$)); + + if (state->ARB_fragment_coord_conventions_enable) { + if (strcmp($1, "origin_upper_left") == 0) { + got_one = true; + $$.flags.q.origin_upper_left = 1; + } else if (strcmp($1, "pixel_center_integer") == 0) { + got_one = true; + $$.flags.q.pixel_center_integer = 1; + } + } + + /* If the identifier didn't match any known layout identifiers, + * emit an error. + */ + if (!got_one) { + _mesa_glsl_error(& @1, state, "unrecognized layout identifier " + "`%s'\n", $1); + YYERROR; + } else if (state->ARB_fragment_coord_conventions_warn) { + _mesa_glsl_warning(& @1, state, + "GL_ARB_fragment_coord_conventions layout " + "identifier `%s' used\n", $1); + } + } + | IDENTIFIER '=' INTCONSTANT + { + bool got_one = false; + + memset(& $$, 0, sizeof($$)); + + if (state->ARB_explicit_attrib_location_enable) { + /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and + * FINISHME: GLSL 1.30 (or later) are supported. + */ + if (strcmp("location", $1) == 0) { + got_one = true; + + $$.flags.q.explicit_location = 1; + + if ($3 >= 0) { + $$.location = $3; + } else { + _mesa_glsl_error(& @3, state, + "invalid location %d specified\n", $3); + YYERROR; + } + } + } + + /* If the identifier didn't match any known layout identifiers, + * emit an error. + */ + if (!got_one) { + _mesa_glsl_error(& @1, state, "unrecognized layout identifier " + "`%s'\n", $1); + YYERROR; + } else if (state->ARB_explicit_attrib_location_warn) { + _mesa_glsl_warning(& @1, state, + "GL_ARB_explicit_attrib_location layout " + "identifier `%s' used\n", $1); + } + } + ; + +interpolation_qualifier: + SMOOTH + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.smooth = 1; + } + | FLAT + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.flat = 1; + } + | NOPERSPECTIVE + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.noperspective = 1; + } + ; + +parameter_type_qualifier: + CONST_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.constant = 1; + } + ; + +type_qualifier: + storage_qualifier + | layout_qualifier + | layout_qualifier storage_qualifier + { + $$ = $1; + $$.flags.i |= $2.flags.i; + } + | interpolation_qualifier + | interpolation_qualifier storage_qualifier + { + $$ = $1; + $$.flags.i |= $2.flags.i; + } + | INVARIANT storage_qualifier + { + $$ = $2; + $$.flags.q.invariant = 1; + } + | INVARIANT interpolation_qualifier storage_qualifier + { + $$ = $2; + $$.flags.i |= $3.flags.i; + $$.flags.q.invariant = 1; + } + | INVARIANT + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.invariant = 1; + } + ; + +storage_qualifier: + CONST_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.constant = 1; + } + | ATTRIBUTE + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.attribute = 1; + } + | VARYING + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.varying = 1; + } + | CENTROID VARYING + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.centroid = 1; + $$.flags.q.varying = 1; + } + | IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.in = 1; + } + | OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.out = 1; + } + | CENTROID IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.centroid = 1; $$.flags.q.in = 1; + } + | CENTROID OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.centroid = 1; $$.flags.q.out = 1; + } + | UNIFORM + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.uniform = 1; + } + ; + +type_specifier: + type_specifier_no_prec + { + $$ = $1; + } + | precision_qualifier type_specifier_no_prec + { + $$ = $2; + $$->precision = $1; + } + ; + +type_specifier_no_prec: + type_specifier_nonarray + | type_specifier_nonarray '[' ']' + { + $$ = $1; + $$->is_array = true; + $$->array_size = NULL; + } + | type_specifier_nonarray '[' constant_expression ']' + { + $$ = $1; + $$->is_array = true; + $$->array_size = $3; + } + ; + +type_specifier_nonarray: + basic_type_specifier_nonarray + { + void *ctx = state; + $$ = new(ctx) ast_type_specifier($1); + $$->set_location(yylloc); + } + | struct_specifier + { + void *ctx = state; + $$ = new(ctx) ast_type_specifier($1); + $$->set_location(yylloc); + } + | IDENTIFIER + { + void *ctx = state; + $$ = new(ctx) ast_type_specifier($1); + $$->set_location(yylloc); + } + ; + +basic_type_specifier_nonarray: + VOID_TOK { $$ = ast_void; } + | FLOAT_TOK { $$ = ast_float; } + | INT_TOK { $$ = ast_int; } + | UINT_TOK { $$ = ast_uint; } + | BOOL_TOK { $$ = ast_bool; } + | VEC2 { $$ = ast_vec2; } + | VEC3 { $$ = ast_vec3; } + | VEC4 { $$ = ast_vec4; } + | BVEC2 { $$ = ast_bvec2; } + | BVEC3 { $$ = ast_bvec3; } + | BVEC4 { $$ = ast_bvec4; } + | IVEC2 { $$ = ast_ivec2; } + | IVEC3 { $$ = ast_ivec3; } + | IVEC4 { $$ = ast_ivec4; } + | UVEC2 { $$ = ast_uvec2; } + | UVEC3 { $$ = ast_uvec3; } + | UVEC4 { $$ = ast_uvec4; } + | MAT2X2 { $$ = ast_mat2; } + | MAT2X3 { $$ = ast_mat2x3; } + | MAT2X4 { $$ = ast_mat2x4; } + | MAT3X2 { $$ = ast_mat3x2; } + | MAT3X3 { $$ = ast_mat3; } + | MAT3X4 { $$ = ast_mat3x4; } + | MAT4X2 { $$ = ast_mat4x2; } + | MAT4X3 { $$ = ast_mat4x3; } + | MAT4X4 { $$ = ast_mat4; } + | SAMPLER1D { $$ = ast_sampler1d; } + | SAMPLER2D { $$ = ast_sampler2d; } + | SAMPLER2DRECT { $$ = ast_sampler2drect; } + | SAMPLER3D { $$ = ast_sampler3d; } + | SAMPLERCUBE { $$ = ast_samplercube; } + | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; } + | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; } + | SAMPLER2DRECTSHADOW { $$ = ast_sampler2drectshadow; } + | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; } + | SAMPLER1DARRAY { $$ = ast_sampler1darray; } + | SAMPLER2DARRAY { $$ = ast_sampler2darray; } + | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; } + | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; } + | ISAMPLER1D { $$ = ast_isampler1d; } + | ISAMPLER2D { $$ = ast_isampler2d; } + | ISAMPLER3D { $$ = ast_isampler3d; } + | ISAMPLERCUBE { $$ = ast_isamplercube; } + | ISAMPLER1DARRAY { $$ = ast_isampler1darray; } + | ISAMPLER2DARRAY { $$ = ast_isampler2darray; } + | USAMPLER1D { $$ = ast_usampler1d; } + | USAMPLER2D { $$ = ast_usampler2d; } + | USAMPLER3D { $$ = ast_usampler3d; } + | USAMPLERCUBE { $$ = ast_usamplercube; } + | USAMPLER1DARRAY { $$ = ast_usampler1darray; } + | USAMPLER2DARRAY { $$ = ast_usampler2darray; } + ; + +precision_qualifier: + HIGHP { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& @1, state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + $$ = ast_precision_high; + } + | MEDIUMP { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& @1, state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + $$ = ast_precision_medium; + } + | LOWP { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& @1, state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + $$ = ast_precision_low; + } + ; + +struct_specifier: + STRUCT IDENTIFIER '{' struct_declaration_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_struct_specifier($2, $4); + $$->set_location(yylloc); + } + | STRUCT '{' struct_declaration_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_struct_specifier(NULL, $3); + $$->set_location(yylloc); + } + ; + +struct_declaration_list: + struct_declaration + { + $$ = (ast_node *) $1; + $1->link.self_link(); + } + | struct_declaration_list struct_declaration + { + $$ = (ast_node *) $1; + $$->link.insert_before(& $2->link); + } + ; + +struct_declaration: + type_specifier struct_declarator_list ';' + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->specifier = $1; + $$ = new(ctx) ast_declarator_list(type); + $$->set_location(yylloc); + + $$->declarations.push_degenerate_list_at_head(& $2->link); + } + ; + +struct_declarator_list: + struct_declarator + { + $$ = $1; + $1->link.self_link(); + } + | struct_declarator_list ',' struct_declarator + { + $$ = $1; + $$->link.insert_before(& $3->link); + } + ; + +struct_declarator: + IDENTIFIER + { + void *ctx = state; + $$ = new(ctx) ast_declaration($1, false, NULL, NULL); + $$->set_location(yylloc); + } + | IDENTIFIER '[' constant_expression ']' + { + void *ctx = state; + $$ = new(ctx) ast_declaration($1, true, $3, NULL); + $$->set_location(yylloc); + } + ; + +initializer: + assignment_expression + ; + +declaration_statement: + declaration + ; + + // Grammar Note: labeled statements for SWITCH only; 'goto' is not + // supported. +statement: + compound_statement { $$ = (ast_node *) $1; } + | simple_statement + ; + +simple_statement: + declaration_statement + | expression_statement + | selection_statement + | switch_statement { $$ = NULL; } + | case_label { $$ = NULL; } + | iteration_statement + | jump_statement + ; + +compound_statement: + '{' '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(true, NULL); + $$->set_location(yylloc); + } + | '{' statement_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(true, $2); + $$->set_location(yylloc); + } + ; + +statement_no_new_scope: + compound_statement_no_new_scope { $$ = (ast_node *) $1; } + | simple_statement + ; + +compound_statement_no_new_scope: + '{' '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(false, NULL); + $$->set_location(yylloc); + } + | '{' statement_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(false, $2); + $$->set_location(yylloc); + } + ; + +statement_list: + statement + { + if ($1 == NULL) { + _mesa_glsl_error(& @1, state, "<nil> statement\n"); + assert($1 != NULL); + } + + $$ = $1; + $$->link.self_link(); + } + | statement_list statement + { + if ($2 == NULL) { + _mesa_glsl_error(& @2, state, "<nil> statement\n"); + assert($2 != NULL); + } + $$ = $1; + $$->link.insert_before(& $2->link); + } + ; + +expression_statement: + ';' + { + void *ctx = state; + $$ = new(ctx) ast_expression_statement(NULL); + $$->set_location(yylloc); + } + | expression ';' + { + void *ctx = state; + $$ = new(ctx) ast_expression_statement($1); + $$->set_location(yylloc); + } + ; + +selection_statement: + IF '(' expression ')' selection_rest_statement + { + $$ = new(state) ast_selection_statement($3, $5.then_statement, + $5.else_statement); + $$->set_location(yylloc); + } + ; + +selection_rest_statement: + statement ELSE statement + { + $$.then_statement = $1; + $$.else_statement = $3; + } + | statement + { + $$.then_statement = $1; + $$.else_statement = NULL; + } + ; + +condition: + expression + { + $$ = (ast_node *) $1; + } + | fully_specified_type IDENTIFIER '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); + ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); + decl->set_location(yylloc); + declarator->set_location(yylloc); + + declarator->declarations.push_tail(&decl->link); + $$ = declarator; + } + ; + +switch_statement: + SWITCH '(' expression ')' compound_statement + ; + +case_label: + CASE expression ':' + | DEFAULT ':' + ; + +iteration_statement: + WHILE '(' condition ')' statement_no_new_scope + { + void *ctx = state; + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, + NULL, $3, NULL, $5); + $$->set_location(yylloc); + } + | DO statement WHILE '(' expression ')' ';' + { + void *ctx = state; + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, + NULL, $5, NULL, $2); + $$->set_location(yylloc); + } + | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope + { + void *ctx = state; + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, + $3, $4.cond, $4.rest, $6); + $$->set_location(yylloc); + } + ; + +for_init_statement: + expression_statement + | declaration_statement + ; + +conditionopt: + condition + | /* empty */ + { + $$ = NULL; + } + ; + +for_rest_statement: + conditionopt ';' + { + $$.cond = $1; + $$.rest = NULL; + } + | conditionopt ';' expression + { + $$.cond = $1; + $$.rest = $3; + } + ; + + // Grammar Note: No 'goto'. Gotos are not supported. +jump_statement: + CONTINUE ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); + $$->set_location(yylloc); + } + | BREAK ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); + $$->set_location(yylloc); + } + | RETURN ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); + $$->set_location(yylloc); + } + | RETURN expression ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); + $$->set_location(yylloc); + } + | DISCARD ';' // Fragment shader only. + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); + $$->set_location(yylloc); + } + ; + +external_declaration: + function_definition { $$ = $1; } + | declaration { $$ = $1; } + | pragma_statement { $$ = NULL; } + ; + +function_definition: + function_prototype compound_statement_no_new_scope + { + void *ctx = state; + $$ = new(ctx) ast_function_definition(); + $$->set_location(yylloc); + $$->prototype = $1; + $$->body = $2; + } + ; diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 373c9008b..77885d4e1 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -1,786 +1,788 @@ -/*
- * Copyright © 2008, 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <assert.h>
-
-extern "C" {
-#include <talloc.h>
-#include "main/core.h" /* for struct gl_context */
-}
-
-#include "ast.h"
-#include "glsl_parser_extras.h"
-#include "glsl_parser.h"
-#include "ir_optimization.h"
-#include "loop_analysis.h"
-
-_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
- GLenum target, void *mem_ctx)
-{
- switch (target) {
- case GL_VERTEX_SHADER: this->target = vertex_shader; break;
- case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
- case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
- }
-
- this->scanner = NULL;
- this->translation_unit.make_empty();
- this->symbols = new(mem_ctx) glsl_symbol_table;
- this->info_log = talloc_strdup(mem_ctx, "");
- this->error = false;
- this->loop_or_switch_nesting = NULL;
-
- /* Set default language version and extensions */
- this->language_version = 110;
- this->es_shader = false;
- this->ARB_texture_rectangle_enable = true;
-
- /* OpenGL ES 2.0 has different defaults from desktop GL. */
- if (ctx->API == API_OPENGLES2) {
- this->language_version = 100;
- this->es_shader = true;
- this->ARB_texture_rectangle_enable = false;
- }
-
- this->extensions = &ctx->Extensions;
-
- this->Const.MaxLights = ctx->Const.MaxLights;
- this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
- this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
- this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
- this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs;
- this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents;
- this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4;
- this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits;
- this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
- this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
- this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
-
- this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
-}
-
-const char *
-_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
-{
- switch (target) {
- case vertex_shader: return "vertex";
- case fragment_shader: return "fragment";
- case geometry_shader: return "geometry";
- }
-
- assert(!"Should not get here.");
- return "unknown";
-}
-
-
-void
-_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
- const char *fmt, ...)
-{
- va_list ap;
-
- state->error = true;
-
- assert(state->info_log != NULL);
- state->info_log = talloc_asprintf_append(state->info_log,
- "%u:%u(%u): error: ",
- locp->source,
- locp->first_line,
- locp->first_column);
- va_start(ap, fmt);
- state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
- va_end(ap);
- state->info_log = talloc_strdup_append(state->info_log, "\n");
-}
-
-
-void
-_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
- const char *fmt, ...)
-{
- va_list ap;
-
- assert(state->info_log != NULL);
- state->info_log = talloc_asprintf_append(state->info_log,
- "%u:%u(%u): warning: ",
- locp->source,
- locp->first_line,
- locp->first_column);
- va_start(ap, fmt);
- state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
- va_end(ap);
- state->info_log = talloc_strdup_append(state->info_log, "\n");
-}
-
-
-bool
-_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
- const char *behavior, YYLTYPE *behavior_locp,
- _mesa_glsl_parse_state *state)
-{
- enum {
- extension_disable,
- extension_enable,
- extension_require,
- extension_warn
- } ext_mode;
-
- if (strcmp(behavior, "warn") == 0) {
- ext_mode = extension_warn;
- } else if (strcmp(behavior, "require") == 0) {
- ext_mode = extension_require;
- } else if (strcmp(behavior, "enable") == 0) {
- ext_mode = extension_enable;
- } else if (strcmp(behavior, "disable") == 0) {
- ext_mode = extension_disable;
- } else {
- _mesa_glsl_error(behavior_locp, state,
- "Unknown extension behavior `%s'",
- behavior);
- return false;
- }
-
- bool unsupported = false;
-
- if (strcmp(name, "all") == 0) {
- if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
- _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
- (ext_mode == extension_enable)
- ? "enable" : "require");
- return false;
- }
- } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
- /* This extension is only supported in fragment shaders.
- */
- if (state->target != fragment_shader) {
- unsupported = true;
- } else {
- state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
- state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
- }
- } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) {
- /* This extension is only supported in vertex shaders.
- */
- if (state->target != vertex_shader) {
- unsupported = true;
- } else {
- state->ARB_draw_instanced_enable = (ext_mode != extension_disable);
- state->ARB_draw_instanced_warn = (ext_mode == extension_warn);
- }
- } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
- state->ARB_explicit_attrib_location_enable =
- (ext_mode != extension_disable);
- state->ARB_explicit_attrib_location_warn =
- (ext_mode == extension_warn);
-
- unsupported = !state->extensions->ARB_explicit_attrib_location;
- } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) {
- state->ARB_fragment_coord_conventions_enable =
- (ext_mode != extension_disable);
- state->ARB_fragment_coord_conventions_warn =
- (ext_mode == extension_warn);
-
- unsupported = !state->extensions->ARB_fragment_coord_conventions;
- } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
- state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
- state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
- } else if (strcmp(name, "GL_EXT_texture_array") == 0) {
- state->EXT_texture_array_enable = (ext_mode != extension_disable);
- state->EXT_texture_array_warn = (ext_mode == extension_warn);
-
- unsupported = !state->extensions->EXT_texture_array;
- } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) {
- if (state->target != fragment_shader) {
- unsupported = true;
- } else {
- state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable);
- state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn);
- unsupported = !state->extensions->ARB_shader_stencil_export;
- }
- } else {
- unsupported = true;
- }
-
- if (unsupported) {
- static const char *const fmt = "extension `%s' unsupported in %s shader";
-
- if (ext_mode == extension_require) {
- _mesa_glsl_error(name_locp, state, fmt,
- name, _mesa_glsl_shader_target_name(state->target));
- return false;
- } else {
- _mesa_glsl_warning(name_locp, state, fmt,
- name, _mesa_glsl_shader_target_name(state->target));
- }
- }
-
- return true;
-}
-
-void
-_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
-{
- if (q->flags.q.constant)
- printf("const ");
-
- if (q->flags.q.invariant)
- printf("invariant ");
-
- if (q->flags.q.attribute)
- printf("attribute ");
-
- if (q->flags.q.varying)
- printf("varying ");
-
- if (q->flags.q.in && q->flags.q.out)
- printf("inout ");
- else {
- if (q->flags.q.in)
- printf("in ");
-
- if (q->flags.q.out)
- printf("out ");
- }
-
- if (q->flags.q.centroid)
- printf("centroid ");
- if (q->flags.q.uniform)
- printf("uniform ");
- if (q->flags.q.smooth)
- printf("smooth ");
- if (q->flags.q.flat)
- printf("flat ");
- if (q->flags.q.noperspective)
- printf("noperspective ");
-}
-
-
-void
-ast_node::print(void) const
-{
- printf("unhandled node ");
-}
-
-
-ast_node::ast_node(void)
-{
- this->location.source = 0;
- this->location.line = 0;
- this->location.column = 0;
-}
-
-
-static void
-ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
-{
- if (is_array) {
- printf("[ ");
-
- if (array_size)
- array_size->print();
-
- printf("] ");
- }
-}
-
-
-void
-ast_compound_statement::print(void) const
-{
- printf("{\n");
-
- foreach_list_const(n, &this->statements) {
- ast_node *ast = exec_node_data(ast_node, n, link);
- ast->print();
- }
-
- printf("}\n");
-}
-
-
-ast_compound_statement::ast_compound_statement(int new_scope,
- ast_node *statements)
-{
- this->new_scope = new_scope;
-
- if (statements != NULL) {
- this->statements.push_degenerate_list_at_head(&statements->link);
- }
-}
-
-
-void
-ast_expression::print(void) const
-{
- switch (oper) {
- case ast_assign:
- case ast_mul_assign:
- case ast_div_assign:
- case ast_mod_assign:
- case ast_add_assign:
- case ast_sub_assign:
- case ast_ls_assign:
- case ast_rs_assign:
- case ast_and_assign:
- case ast_xor_assign:
- case ast_or_assign:
- subexpressions[0]->print();
- printf("%s ", operator_string(oper));
- subexpressions[1]->print();
- break;
-
- case ast_field_selection:
- subexpressions[0]->print();
- printf(". %s ", primary_expression.identifier);
- break;
-
- case ast_plus:
- case ast_neg:
- case ast_bit_not:
- case ast_logic_not:
- case ast_pre_inc:
- case ast_pre_dec:
- printf("%s ", operator_string(oper));
- subexpressions[0]->print();
- break;
-
- case ast_post_inc:
- case ast_post_dec:
- subexpressions[0]->print();
- printf("%s ", operator_string(oper));
- break;
-
- case ast_conditional:
- subexpressions[0]->print();
- printf("? ");
- subexpressions[1]->print();
- printf(": ");
- subexpressions[1]->print();
- break;
-
- case ast_array_index:
- subexpressions[0]->print();
- printf("[ ");
- subexpressions[1]->print();
- printf("] ");
- break;
-
- case ast_function_call: {
- subexpressions[0]->print();
- printf("( ");
-
- foreach_list_const (n, &this->expressions) {
- if (n != this->expressions.get_head())
- printf(", ");
-
- ast_node *ast = exec_node_data(ast_node, n, link);
- ast->print();
- }
-
- printf(") ");
- break;
- }
-
- case ast_identifier:
- printf("%s ", primary_expression.identifier);
- break;
-
- case ast_int_constant:
- printf("%d ", primary_expression.int_constant);
- break;
-
- case ast_uint_constant:
- printf("%u ", primary_expression.uint_constant);
- break;
-
- case ast_float_constant:
- printf("%f ", primary_expression.float_constant);
- break;
-
- case ast_bool_constant:
- printf("%s ",
- primary_expression.bool_constant
- ? "true" : "false");
- break;
-
- case ast_sequence: {
- printf("( ");
- foreach_list_const(n, & this->expressions) {
- if (n != this->expressions.get_head())
- printf(", ");
-
- ast_node *ast = exec_node_data(ast_node, n, link);
- ast->print();
- }
- printf(") ");
- break;
- }
-
- default:
- assert(0);
- break;
- }
-}
-
-ast_expression::ast_expression(int oper,
- ast_expression *ex0,
- ast_expression *ex1,
- ast_expression *ex2)
-{
- this->oper = ast_operators(oper);
- this->subexpressions[0] = ex0;
- this->subexpressions[1] = ex1;
- this->subexpressions[2] = ex2;
-}
-
-
-void
-ast_expression_statement::print(void) const
-{
- if (expression)
- expression->print();
-
- printf("; ");
-}
-
-
-ast_expression_statement::ast_expression_statement(ast_expression *ex) :
- expression(ex)
-{
- /* empty */
-}
-
-
-void
-ast_function::print(void) const
-{
- return_type->print();
- printf(" %s (", identifier);
-
- foreach_list_const(n, & this->parameters) {
- ast_node *ast = exec_node_data(ast_node, n, link);
- ast->print();
- }
-
- printf(")");
-}
-
-
-ast_function::ast_function(void)
- : is_definition(false), signature(NULL)
-{
- /* empty */
-}
-
-
-void
-ast_fully_specified_type::print(void) const
-{
- _mesa_ast_type_qualifier_print(& qualifier);
- specifier->print();
-}
-
-
-void
-ast_parameter_declarator::print(void) const
-{
- type->print();
- if (identifier)
- printf("%s ", identifier);
- ast_opt_array_size_print(is_array, array_size);
-}
-
-
-void
-ast_function_definition::print(void) const
-{
- prototype->print();
- body->print();
-}
-
-
-void
-ast_declaration::print(void) const
-{
- printf("%s ", identifier);
- ast_opt_array_size_print(is_array, array_size);
-
- if (initializer) {
- printf("= ");
- initializer->print();
- }
-}
-
-
-ast_declaration::ast_declaration(char *identifier, int is_array,
- ast_expression *array_size,
- ast_expression *initializer)
-{
- this->identifier = identifier;
- this->is_array = is_array;
- this->array_size = array_size;
- this->initializer = initializer;
-}
-
-
-void
-ast_declarator_list::print(void) const
-{
- assert(type || invariant);
-
- if (type)
- type->print();
- else
- printf("invariant ");
-
- foreach_list_const (ptr, & this->declarations) {
- if (ptr != this->declarations.get_head())
- printf(", ");
-
- ast_node *ast = exec_node_data(ast_node, ptr, link);
- ast->print();
- }
-
- printf("; ");
-}
-
-
-ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
-{
- this->type = type;
- this->invariant = false;
-}
-
-void
-ast_jump_statement::print(void) const
-{
- switch (mode) {
- case ast_continue:
- printf("continue; ");
- break;
- case ast_break:
- printf("break; ");
- break;
- case ast_return:
- printf("return ");
- if (opt_return_value)
- opt_return_value->print();
-
- printf("; ");
- break;
- case ast_discard:
- printf("discard; ");
- break;
- }
-}
-
-
-ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
-{
- this->mode = ast_jump_modes(mode);
-
- if (mode == ast_return)
- opt_return_value = return_value;
-}
-
-
-void
-ast_selection_statement::print(void) const
-{
- printf("if ( ");
- condition->print();
- printf(") ");
-
- then_statement->print();
-
- if (else_statement) {
- printf("else ");
- else_statement->print();
- }
-
-}
-
-
-ast_selection_statement::ast_selection_statement(ast_expression *condition,
- ast_node *then_statement,
- ast_node *else_statement)
-{
- this->condition = condition;
- this->then_statement = then_statement;
- this->else_statement = else_statement;
-}
-
-
-void
-ast_iteration_statement::print(void) const
-{
- switch (mode) {
- case ast_for:
- printf("for( ");
- if (init_statement)
- init_statement->print();
- printf("; ");
-
- if (condition)
- condition->print();
- printf("; ");
-
- if (rest_expression)
- rest_expression->print();
- printf(") ");
-
- body->print();
- break;
-
- case ast_while:
- printf("while ( ");
- if (condition)
- condition->print();
- printf(") ");
- body->print();
- break;
-
- case ast_do_while:
- printf("do ");
- body->print();
- printf("while ( ");
- if (condition)
- condition->print();
- printf("); ");
- break;
- }
-}
-
-
-ast_iteration_statement::ast_iteration_statement(int mode,
- ast_node *init,
- ast_node *condition,
- ast_expression *rest_expression,
- ast_node *body)
-{
- this->mode = ast_iteration_modes(mode);
- this->init_statement = init;
- this->condition = condition;
- this->rest_expression = rest_expression;
- this->body = body;
-}
-
-
-void
-ast_struct_specifier::print(void) const
-{
- printf("struct %s { ", name);
- foreach_list_const(n, &this->declarations) {
- ast_node *ast = exec_node_data(ast_node, n, link);
- ast->print();
- }
- printf("} ");
-}
-
-
-ast_struct_specifier::ast_struct_specifier(char *identifier,
- ast_node *declarator_list)
-{
- if (identifier == NULL) {
- static unsigned anon_count = 1;
- identifier = talloc_asprintf(this, "#anon_struct_%04x", anon_count);
- anon_count++;
- }
- name = identifier;
- this->declarations.push_degenerate_list_at_head(&declarator_list->link);
-}
-
-bool
-do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
-{
- GLboolean progress = GL_FALSE;
-
- progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
-
- if (linked) {
- progress = do_function_inlining(ir) || progress;
- progress = do_dead_functions(ir) || progress;
- }
- progress = do_structure_splitting(ir) || progress;
- progress = do_if_simplification(ir) || progress;
- progress = do_discard_simplification(ir) || progress;
- progress = do_copy_propagation(ir) || progress;
- if (linked)
- progress = do_dead_code(ir) || progress;
- else
- progress = do_dead_code_unlinked(ir) || progress;
- progress = do_dead_code_local(ir) || progress;
- progress = do_tree_grafting(ir) || progress;
- progress = do_constant_propagation(ir) || progress;
- if (linked)
- progress = do_constant_variable(ir) || progress;
- else
- progress = do_constant_variable_unlinked(ir) || progress;
- progress = do_constant_folding(ir) || progress;
- progress = do_algebraic(ir) || progress;
- progress = do_lower_jumps(ir) || progress;
- progress = do_vec_index_to_swizzle(ir) || progress;
- progress = do_swizzle_swizzle(ir) || progress;
- progress = do_noop_swizzle(ir) || progress;
-
- progress = optimize_redundant_jumps(ir) || progress;
-
- loop_state *ls = analyze_loop_variables(ir);
- progress = set_loop_controls(ir, ls) || progress;
- progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
- delete ls;
-
- return progress;
-}
-
-extern "C" {
-
-/**
- * To be called at GL teardown time, this frees compiler datastructures.
- *
- * After calling this, any previously compiled shaders and shader
- * programs would be invalid. So this should happen at approximately
- * program exit.
- */
-void
-_mesa_destroy_shader_compiler(void)
-{
- _mesa_destroy_shader_compiler_caches();
-
- _mesa_glsl_release_types();
-}
-
-/**
- * Releases compiler caches to trade off performance for memory.
- *
- * Intended to be used with glReleaseShaderCompiler().
- */
-void
-_mesa_destroy_shader_compiler_caches(void)
-{
- _mesa_glsl_release_functions();
-}
-
-}
+/* + * Copyright © 2008, 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <assert.h> + +extern "C" { +#include <talloc.h> +#include "main/core.h" /* for struct gl_context */ +} + +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_parser.h" +#include "ir_optimization.h" +#include "loop_analysis.h" + +_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx, + GLenum target, void *mem_ctx) +{ + switch (target) { + case GL_VERTEX_SHADER: this->target = vertex_shader; break; + case GL_FRAGMENT_SHADER: this->target = fragment_shader; break; + case GL_GEOMETRY_SHADER: this->target = geometry_shader; break; + } + + this->scanner = NULL; + this->translation_unit.make_empty(); + this->symbols = new(mem_ctx) glsl_symbol_table; + this->info_log = talloc_strdup(mem_ctx, ""); + this->error = false; + this->loop_or_switch_nesting = NULL; + + /* Set default language version and extensions */ + this->language_version = 110; + this->es_shader = false; + this->ARB_texture_rectangle_enable = true; + + /* OpenGL ES 2.0 has different defaults from desktop GL. */ + if (ctx->API == API_OPENGLES2) { + this->language_version = 100; + this->es_shader = true; + this->ARB_texture_rectangle_enable = false; + } + + this->extensions = &ctx->Extensions; + + this->Const.MaxLights = ctx->Const.MaxLights; + this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes; + this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits; + this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; + this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs; + this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents; + this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4; + this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits; + this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; + this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; + this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents; + + this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; +} + +const char * +_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) +{ + switch (target) { + case vertex_shader: return "vertex"; + case fragment_shader: return "fragment"; + case geometry_shader: return "geometry"; + } + + assert(!"Should not get here."); + return "unknown"; +} + + +void +_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, + const char *fmt, ...) +{ + va_list ap; + + state->error = true; + + assert(state->info_log != NULL); + state->info_log = talloc_asprintf_append(state->info_log, + "%u:%u(%u): error: ", + locp->source, + locp->first_line, + locp->first_column); + va_start(ap, fmt); + state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap); + va_end(ap); + state->info_log = talloc_strdup_append(state->info_log, "\n"); +} + + +void +_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, + const char *fmt, ...) +{ + va_list ap; + + assert(state->info_log != NULL); + state->info_log = talloc_asprintf_append(state->info_log, + "%u:%u(%u): warning: ", + locp->source, + locp->first_line, + locp->first_column); + va_start(ap, fmt); + state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap); + va_end(ap); + state->info_log = talloc_strdup_append(state->info_log, "\n"); +} + + +bool +_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, + const char *behavior, YYLTYPE *behavior_locp, + _mesa_glsl_parse_state *state) +{ + enum { + extension_disable, + extension_enable, + extension_require, + extension_warn + } ext_mode; + + if (strcmp(behavior, "warn") == 0) { + ext_mode = extension_warn; + } else if (strcmp(behavior, "require") == 0) { + ext_mode = extension_require; + } else if (strcmp(behavior, "enable") == 0) { + ext_mode = extension_enable; + } else if (strcmp(behavior, "disable") == 0) { + ext_mode = extension_disable; + } else { + _mesa_glsl_error(behavior_locp, state, + "Unknown extension behavior `%s'", + behavior); + return false; + } + + bool unsupported = false; + + if (strcmp(name, "all") == 0) { + if ((ext_mode == extension_enable) || (ext_mode == extension_require)) { + _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", + (ext_mode == extension_enable) + ? "enable" : "require"); + return false; + } + } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) { + /* This extension is only supported in fragment shaders. + */ + if (state->target != fragment_shader) { + unsupported = true; + } else { + state->ARB_draw_buffers_enable = (ext_mode != extension_disable); + state->ARB_draw_buffers_warn = (ext_mode == extension_warn); + } + } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) { + /* This extension is only supported in vertex shaders. + */ + if (state->target != vertex_shader) { + unsupported = true; + } else { + state->ARB_draw_instanced_enable = (ext_mode != extension_disable); + state->ARB_draw_instanced_warn = (ext_mode == extension_warn); + } + } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) { + state->ARB_explicit_attrib_location_enable = + (ext_mode != extension_disable); + state->ARB_explicit_attrib_location_warn = + (ext_mode == extension_warn); + + unsupported = !state->extensions->ARB_explicit_attrib_location; + } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) { + state->ARB_fragment_coord_conventions_enable = + (ext_mode != extension_disable); + state->ARB_fragment_coord_conventions_warn = + (ext_mode == extension_warn); + + unsupported = !state->extensions->ARB_fragment_coord_conventions; + } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) { + state->ARB_texture_rectangle_enable = (ext_mode != extension_disable); + state->ARB_texture_rectangle_warn = (ext_mode == extension_warn); + } else if (strcmp(name, "GL_EXT_texture_array") == 0) { + state->EXT_texture_array_enable = (ext_mode != extension_disable); + state->EXT_texture_array_warn = (ext_mode == extension_warn); + + unsupported = !state->extensions->EXT_texture_array; + } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) { + if (state->target != fragment_shader) { + unsupported = true; + } else { + state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable); + state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn); + unsupported = !state->extensions->ARB_shader_stencil_export; + } + } else { + unsupported = true; + } + + if (unsupported) { + static const char *const fmt = "extension `%s' unsupported in %s shader"; + + if (ext_mode == extension_require) { + _mesa_glsl_error(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + return false; + } else { + _mesa_glsl_warning(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + } + } + + return true; +} + +void +_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) +{ + if (q->flags.q.constant) + printf("const "); + + if (q->flags.q.invariant) + printf("invariant "); + + if (q->flags.q.attribute) + printf("attribute "); + + if (q->flags.q.varying) + printf("varying "); + + if (q->flags.q.in && q->flags.q.out) + printf("inout "); + else { + if (q->flags.q.in) + printf("in "); + + if (q->flags.q.out) + printf("out "); + } + + if (q->flags.q.centroid) + printf("centroid "); + if (q->flags.q.uniform) + printf("uniform "); + if (q->flags.q.smooth) + printf("smooth "); + if (q->flags.q.flat) + printf("flat "); + if (q->flags.q.noperspective) + printf("noperspective "); +} + + +void +ast_node::print(void) const +{ + printf("unhandled node "); +} + + +ast_node::ast_node(void) +{ + this->location.source = 0; + this->location.line = 0; + this->location.column = 0; +} + + +static void +ast_opt_array_size_print(bool is_array, const ast_expression *array_size) +{ + if (is_array) { + printf("[ "); + + if (array_size) + array_size->print(); + + printf("] "); + } +} + + +void +ast_compound_statement::print(void) const +{ + printf("{\n"); + + foreach_list_const(n, &this->statements) { + ast_node *ast = exec_node_data(ast_node, n, link); + ast->print(); + } + + printf("}\n"); +} + + +ast_compound_statement::ast_compound_statement(int new_scope, + ast_node *statements) +{ + this->new_scope = new_scope; + + if (statements != NULL) { + this->statements.push_degenerate_list_at_head(&statements->link); + } +} + + +void +ast_expression::print(void) const +{ + switch (oper) { + case ast_assign: + case ast_mul_assign: + case ast_div_assign: + case ast_mod_assign: + case ast_add_assign: + case ast_sub_assign: + case ast_ls_assign: + case ast_rs_assign: + case ast_and_assign: + case ast_xor_assign: + case ast_or_assign: + subexpressions[0]->print(); + printf("%s ", operator_string(oper)); + subexpressions[1]->print(); + break; + + case ast_field_selection: + subexpressions[0]->print(); + printf(". %s ", primary_expression.identifier); + break; + + case ast_plus: + case ast_neg: + case ast_bit_not: + case ast_logic_not: + case ast_pre_inc: + case ast_pre_dec: + printf("%s ", operator_string(oper)); + subexpressions[0]->print(); + break; + + case ast_post_inc: + case ast_post_dec: + subexpressions[0]->print(); + printf("%s ", operator_string(oper)); + break; + + case ast_conditional: + subexpressions[0]->print(); + printf("? "); + subexpressions[1]->print(); + printf(": "); + subexpressions[1]->print(); + break; + + case ast_array_index: + subexpressions[0]->print(); + printf("[ "); + subexpressions[1]->print(); + printf("] "); + break; + + case ast_function_call: { + subexpressions[0]->print(); + printf("( "); + + foreach_list_const (n, &this->expressions) { + if (n != this->expressions.get_head()) + printf(", "); + + ast_node *ast = exec_node_data(ast_node, n, link); + ast->print(); + } + + printf(") "); + break; + } + + case ast_identifier: + printf("%s ", primary_expression.identifier); + break; + + case ast_int_constant: + printf("%d ", primary_expression.int_constant); + break; + + case ast_uint_constant: + printf("%u ", primary_expression.uint_constant); + break; + + case ast_float_constant: + printf("%f ", primary_expression.float_constant); + break; + + case ast_bool_constant: + printf("%s ", + primary_expression.bool_constant + ? "true" : "false"); + break; + + case ast_sequence: { + printf("( "); + foreach_list_const(n, & this->expressions) { + if (n != this->expressions.get_head()) + printf(", "); + + ast_node *ast = exec_node_data(ast_node, n, link); + ast->print(); + } + printf(") "); + break; + } + + default: + assert(0); + break; + } +} + +ast_expression::ast_expression(int oper, + ast_expression *ex0, + ast_expression *ex1, + ast_expression *ex2) +{ + this->oper = ast_operators(oper); + this->subexpressions[0] = ex0; + this->subexpressions[1] = ex1; + this->subexpressions[2] = ex2; +} + + +void +ast_expression_statement::print(void) const +{ + if (expression) + expression->print(); + + printf("; "); +} + + +ast_expression_statement::ast_expression_statement(ast_expression *ex) : + expression(ex) +{ + /* empty */ +} + + +void +ast_function::print(void) const +{ + return_type->print(); + printf(" %s (", identifier); + + foreach_list_const(n, & this->parameters) { + ast_node *ast = exec_node_data(ast_node, n, link); + ast->print(); + } + + printf(")"); +} + + +ast_function::ast_function(void) + : is_definition(false), signature(NULL) +{ + /* empty */ +} + + +void +ast_fully_specified_type::print(void) const +{ + _mesa_ast_type_qualifier_print(& qualifier); + specifier->print(); +} + + +void +ast_parameter_declarator::print(void) const +{ + type->print(); + if (identifier) + printf("%s ", identifier); + ast_opt_array_size_print(is_array, array_size); +} + + +void +ast_function_definition::print(void) const +{ + prototype->print(); + body->print(); +} + + +void +ast_declaration::print(void) const +{ + printf("%s ", identifier); + ast_opt_array_size_print(is_array, array_size); + + if (initializer) { + printf("= "); + initializer->print(); + } +} + + +ast_declaration::ast_declaration(char *identifier, int is_array, + ast_expression *array_size, + ast_expression *initializer) +{ + this->identifier = identifier; + this->is_array = is_array; + this->array_size = array_size; + this->initializer = initializer; +} + + +void +ast_declarator_list::print(void) const +{ + assert(type || invariant); + + if (type) + type->print(); + else + printf("invariant "); + + foreach_list_const (ptr, & this->declarations) { + if (ptr != this->declarations.get_head()) + printf(", "); + + ast_node *ast = exec_node_data(ast_node, ptr, link); + ast->print(); + } + + printf("; "); +} + + +ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) +{ + this->type = type; + this->invariant = false; +} + +void +ast_jump_statement::print(void) const +{ + switch (mode) { + case ast_continue: + printf("continue; "); + break; + case ast_break: + printf("break; "); + break; + case ast_return: + printf("return "); + if (opt_return_value) + opt_return_value->print(); + + printf("; "); + break; + case ast_discard: + printf("discard; "); + break; + } +} + + +ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value) +{ + this->mode = ast_jump_modes(mode); + + if (mode == ast_return) + opt_return_value = return_value; +} + + +void +ast_selection_statement::print(void) const +{ + printf("if ( "); + condition->print(); + printf(") "); + + then_statement->print(); + + if (else_statement) { + printf("else "); + else_statement->print(); + } + +} + + +ast_selection_statement::ast_selection_statement(ast_expression *condition, + ast_node *then_statement, + ast_node *else_statement) +{ + this->condition = condition; + this->then_statement = then_statement; + this->else_statement = else_statement; +} + + +void +ast_iteration_statement::print(void) const +{ + switch (mode) { + case ast_for: + printf("for( "); + if (init_statement) + init_statement->print(); + printf("; "); + + if (condition) + condition->print(); + printf("; "); + + if (rest_expression) + rest_expression->print(); + printf(") "); + + body->print(); + break; + + case ast_while: + printf("while ( "); + if (condition) + condition->print(); + printf(") "); + body->print(); + break; + + case ast_do_while: + printf("do "); + body->print(); + printf("while ( "); + if (condition) + condition->print(); + printf("); "); + break; + } +} + + +ast_iteration_statement::ast_iteration_statement(int mode, + ast_node *init, + ast_node *condition, + ast_expression *rest_expression, + ast_node *body) +{ + this->mode = ast_iteration_modes(mode); + this->init_statement = init; + this->condition = condition; + this->rest_expression = rest_expression; + this->body = body; +} + + +void +ast_struct_specifier::print(void) const +{ + printf("struct %s { ", name); + foreach_list_const(n, &this->declarations) { + ast_node *ast = exec_node_data(ast_node, n, link); + ast->print(); + } + printf("} "); +} + + +ast_struct_specifier::ast_struct_specifier(char *identifier, + ast_node *declarator_list) +{ + if (identifier == NULL) { + static unsigned anon_count = 1; + identifier = talloc_asprintf(this, "#anon_struct_%04x", anon_count); + anon_count++; + } + name = identifier; + this->declarations.push_degenerate_list_at_head(&declarator_list->link); +} + +bool +do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations) +{ + GLboolean progress = GL_FALSE; + + progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress; + + if (linked) { + progress = do_function_inlining(ir) || progress; + progress = do_dead_functions(ir) || progress; + } + progress = do_structure_splitting(ir) || progress; + progress = do_if_simplification(ir) || progress; + progress = do_discard_simplification(ir) || progress; + progress = do_copy_propagation(ir) || progress; + if (linked) + progress = do_dead_code(ir) || progress; + else + progress = do_dead_code_unlinked(ir) || progress; + progress = do_dead_code_local(ir) || progress; + progress = do_tree_grafting(ir) || progress; + progress = do_constant_propagation(ir) || progress; + if (linked) + progress = do_constant_variable(ir) || progress; + else + progress = do_constant_variable_unlinked(ir) || progress; + progress = do_constant_folding(ir) || progress; + progress = do_algebraic(ir) || progress; + progress = do_lower_jumps(ir) || progress; + progress = do_vec_index_to_swizzle(ir) || progress; + progress = do_swizzle_swizzle(ir) || progress; + progress = do_noop_swizzle(ir) || progress; + + progress = optimize_redundant_jumps(ir) || progress; + + loop_state *ls = analyze_loop_variables(ir); + if (ls->loop_found) { + progress = set_loop_controls(ir, ls) || progress; + progress = unroll_loops(ir, ls, max_unroll_iterations) || progress; + } + delete ls; + + return progress; +} + +extern "C" { + +/** + * To be called at GL teardown time, this frees compiler datastructures. + * + * After calling this, any previously compiled shaders and shader + * programs would be invalid. So this should happen at approximately + * program exit. + */ +void +_mesa_destroy_shader_compiler(void) +{ + _mesa_destroy_shader_compiler_caches(); + + _mesa_glsl_release_types(); +} + +/** + * Releases compiler caches to trade off performance for memory. + * + * Intended to be used with glReleaseShaderCompiler(). + */ +void +_mesa_destroy_shader_compiler_caches(void) +{ + _mesa_glsl_release_functions(); +} + +} diff --git a/mesalib/src/glsl/loop_analysis.cpp b/mesalib/src/glsl/loop_analysis.cpp index f32b91ce8..3cf86ebaa 100644 --- a/mesalib/src/glsl/loop_analysis.cpp +++ b/mesalib/src/glsl/loop_analysis.cpp @@ -1,497 +1,500 @@ -/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "glsl_types.h"
-#include "loop_analysis.h"
-#include "ir_hierarchical_visitor.h"
-
-static bool is_loop_terminator(ir_if *ir);
-
-static bool all_expression_operands_are_loop_constant(ir_rvalue *,
- hash_table *);
-
-static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table *);
-
-
-loop_state::loop_state()
-{
- this->ht = hash_table_ctor(0, hash_table_pointer_hash,
- hash_table_pointer_compare);
- this->mem_ctx = talloc_init("loop state");
-}
-
-
-loop_state::~loop_state()
-{
- hash_table_dtor(this->ht);
- talloc_free(this->mem_ctx);
-}
-
-
-loop_variable_state *
-loop_state::insert(ir_loop *ir)
-{
- loop_variable_state *ls = new(this->mem_ctx) loop_variable_state;
- hash_table_insert(this->ht, ls, ir);
-
- return ls;
-}
-
-
-loop_variable_state *
-loop_state::get(const ir_loop *ir)
-{
- return (loop_variable_state *) hash_table_find(this->ht, ir);
-}
-
-
-loop_variable *
-loop_variable_state::get(const ir_variable *ir)
-{
- return (loop_variable *) hash_table_find(this->var_hash, ir);
-}
-
-
-loop_variable *
-loop_variable_state::insert(ir_variable *var)
-{
- void *mem_ctx = talloc_parent(this);
- loop_variable *lv = talloc_zero(mem_ctx, loop_variable);
-
- lv->var = var;
-
- hash_table_insert(this->var_hash, lv, lv->var);
- this->variables.push_tail(lv);
-
- return lv;
-}
-
-
-loop_terminator *
-loop_variable_state::insert(ir_if *if_stmt)
-{
- void *mem_ctx = talloc_parent(this);
- loop_terminator *t = talloc_zero(mem_ctx, loop_terminator);
-
- t->ir = if_stmt;
- this->terminators.push_tail(t);
-
- return t;
-}
-
-
-class loop_analysis : public ir_hierarchical_visitor {
-public:
- loop_analysis();
-
- virtual ir_visitor_status visit(ir_loop_jump *);
- virtual ir_visitor_status visit(ir_dereference_variable *);
-
- virtual ir_visitor_status visit_enter(ir_loop *);
- virtual ir_visitor_status visit_leave(ir_loop *);
- virtual ir_visitor_status visit_enter(ir_assignment *);
- virtual ir_visitor_status visit_leave(ir_assignment *);
- virtual ir_visitor_status visit_enter(ir_if *);
- virtual ir_visitor_status visit_leave(ir_if *);
-
- loop_state *loops;
-
- int if_statement_depth;
-
- ir_assignment *current_assignment;
-
- exec_list state;
-};
-
-
-loop_analysis::loop_analysis()
-{
- this->loops = new loop_state;
-
- this->if_statement_depth = 0;
- this->current_assignment = NULL;
-}
-
-
-ir_visitor_status
-loop_analysis::visit(ir_loop_jump *ir)
-{
- (void) ir;
-
- assert(!this->state.is_empty());
-
- loop_variable_state *const ls =
- (loop_variable_state *) this->state.get_head();
-
- ls->num_loop_jumps++;
-
- return visit_continue;
-}
-
-
-ir_visitor_status
-loop_analysis::visit(ir_dereference_variable *ir)
-{
- /* If we're not somewhere inside a loop, there's nothing to do.
- */
- if (this->state.is_empty())
- return visit_continue;
-
- loop_variable_state *const ls =
- (loop_variable_state *) this->state.get_head();
-
- ir_variable *var = ir->variable_referenced();
- loop_variable *lv = ls->get(var);
-
- if (lv == NULL) {
- lv = ls->insert(var);
- lv->read_before_write = !this->in_assignee;
- }
-
- if (this->in_assignee) {
- assert(this->current_assignment != NULL);
-
- lv->conditional_assignment = (this->if_statement_depth > 0)
- || (this->current_assignment->condition != NULL);
-
- if (lv->first_assignment == NULL) {
- assert(lv->num_assignments == 0);
-
- lv->first_assignment = this->current_assignment;
- }
-
- lv->num_assignments++;
- } else if (lv->first_assignment == this->current_assignment) {
- /* This catches the case where the variable is used in the RHS of an
- * assignment where it is also in the LHS.
- */
- lv->read_before_write = true;
- }
-
- return visit_continue;
-}
-
-ir_visitor_status
-loop_analysis::visit_enter(ir_loop *ir)
-{
- loop_variable_state *ls = this->loops->insert(ir);
- this->state.push_head(ls);
-
- return visit_continue;
-}
-
-ir_visitor_status
-loop_analysis::visit_leave(ir_loop *ir)
-{
- loop_variable_state *const ls =
- (loop_variable_state *) this->state.pop_head();
-
-
- foreach_list(node, &ir->body_instructions) {
- /* Skip over declarations at the start of a loop.
- */
- if (((ir_instruction *) node)->as_variable())
- continue;
-
- ir_if *if_stmt = ((ir_instruction *) node)->as_if();
-
- if ((if_stmt != NULL) && is_loop_terminator(if_stmt))
- ls->insert(if_stmt);
- else
- break;
- }
-
-
- foreach_list_safe(node, &ls->variables) {
- loop_variable *lv = (loop_variable *) node;
-
- /* Move variables that are already marked as being loop constant to
- * a separate list. These trivially don't need to be tested.
- */
- if (lv->is_loop_constant()) {
- lv->remove();
- ls->constants.push_tail(lv);
- }
- }
-
- /* Each variable assigned in the loop that isn't already marked as being loop
- * constant might still be loop constant. The requirements at this point
- * are:
- *
- * - Variable is written before it is read.
- *
- * - Only one assignment to the variable.
- *
- * - All operands on the RHS of the assignment are also loop constants.
- *
- * The last requirement is the reason for the progress loop. A variable
- * marked as a loop constant on one pass may allow other variables to be
- * marked as loop constant on following passes.
- */
- bool progress;
- do {
- progress = false;
-
- foreach_list_safe(node, &ls->variables) {
- loop_variable *lv = (loop_variable *) node;
-
- if (lv->conditional_assignment || (lv->num_assignments > 1))
- continue;
-
- /* Process the RHS of the assignment. If all of the variables
- * accessed there are loop constants, then add this
- */
- ir_rvalue *const rhs = lv->first_assignment->rhs;
- if (all_expression_operands_are_loop_constant(rhs, ls->var_hash)) {
- lv->rhs_clean = true;
-
- if (lv->is_loop_constant()) {
- progress = true;
-
- lv->remove();
- ls->constants.push_tail(lv);
- }
- }
- }
- } while (progress);
-
- /* The remaining variables that are not loop invariant might be loop
- * induction variables.
- */
- foreach_list_safe(node, &ls->variables) {
- loop_variable *lv = (loop_variable *) node;
-
- /* If there is more than one assignment to a variable, it cannot be a
- * loop induction variable. This isn't strictly true, but this is a
- * very simple induction variable detector, and it can't handle more
- * complex cases.
- */
- if (lv->num_assignments > 1)
- continue;
-
- /* All of the variables with zero assignments in the loop are loop
- * invariant, and they should have already been filtered out.
- */
- assert(lv->num_assignments == 1);
- assert(lv->first_assignment != NULL);
-
- /* The assignmnet to the variable in the loop must be unconditional.
- */
- if (lv->conditional_assignment)
- continue;
-
- /* Basic loop induction variables have a single assignment in the loop
- * that has the form 'VAR = VAR + i' or 'VAR = VAR - i' where i is a
- * loop invariant.
- */
- ir_rvalue *const inc =
- get_basic_induction_increment(lv->first_assignment, ls->var_hash);
- if (inc != NULL) {
- lv->iv_scale = NULL;
- lv->biv = lv->var;
- lv->increment = inc;
-
- lv->remove();
- ls->induction_variables.push_tail(lv);
- }
- }
-
- return visit_continue;
-}
-
-ir_visitor_status
-loop_analysis::visit_enter(ir_if *ir)
-{
- (void) ir;
-
- if (!this->state.is_empty())
- this->if_statement_depth++;
-
- return visit_continue;
-}
-
-ir_visitor_status
-loop_analysis::visit_leave(ir_if *ir)
-{
- (void) ir;
-
- if (!this->state.is_empty())
- this->if_statement_depth--;
-
- return visit_continue;
-}
-
-ir_visitor_status
-loop_analysis::visit_enter(ir_assignment *ir)
-{
- /* If we're not somewhere inside a loop, there's nothing to do.
- */
- if (this->state.is_empty())
- return visit_continue_with_parent;
-
- this->current_assignment = ir;
-
- return visit_continue;
-}
-
-ir_visitor_status
-loop_analysis::visit_leave(ir_assignment *ir)
-{
- /* Since the visit_enter exits with visit_continue_with_parent for this
- * case, the loop state stack should never be empty here.
- */
- assert(!this->state.is_empty());
-
- assert(this->current_assignment == ir);
- this->current_assignment = NULL;
-
- return visit_continue;
-}
-
-
-class examine_rhs : public ir_hierarchical_visitor {
-public:
- examine_rhs(hash_table *loop_variables)
- {
- this->only_uses_loop_constants = true;
- this->loop_variables = loop_variables;
- }
-
- virtual ir_visitor_status visit(ir_dereference_variable *ir)
- {
- loop_variable *lv =
- (loop_variable *) hash_table_find(this->loop_variables, ir->var);
-
- assert(lv != NULL);
-
- if (lv->is_loop_constant()) {
- return visit_continue;
- } else {
- this->only_uses_loop_constants = false;
- return visit_stop;
- }
- }
-
- hash_table *loop_variables;
- bool only_uses_loop_constants;
-};
-
-
-bool
-all_expression_operands_are_loop_constant(ir_rvalue *ir, hash_table *variables)
-{
- examine_rhs v(variables);
-
- ir->accept(&v);
-
- return v.only_uses_loop_constants;
-}
-
-
-ir_rvalue *
-get_basic_induction_increment(ir_assignment *ir, hash_table *var_hash)
-{
- /* The RHS must be a binary expression.
- */
- ir_expression *const rhs = ir->rhs->as_expression();
- if ((rhs == NULL)
- || ((rhs->operation != ir_binop_add)
- && (rhs->operation != ir_binop_sub)))
- return NULL;
-
- /* One of the of operands of the expression must be the variable assigned.
- * If the operation is subtraction, the variable in question must be the
- * "left" operand.
- */
- ir_variable *const var = ir->lhs->variable_referenced();
-
- ir_variable *const op0 = rhs->operands[0]->variable_referenced();
- ir_variable *const op1 = rhs->operands[1]->variable_referenced();
-
- if (((op0 != var) && (op1 != var))
- || ((op1 == var) && (rhs->operation == ir_binop_sub)))
- return NULL;
-
- ir_rvalue *inc = (op0 == var) ? rhs->operands[1] : rhs->operands[0];
-
- if (inc->as_constant() == NULL) {
- ir_variable *const inc_var = inc->variable_referenced();
- if (inc_var != NULL) {
- loop_variable *lv =
- (loop_variable *) hash_table_find(var_hash, inc_var);
-
- if (!lv->is_loop_constant())
- inc = NULL;
- } else
- inc = NULL;
- }
-
- if ((inc != NULL) && (rhs->operation == ir_binop_sub)) {
- void *mem_ctx = talloc_parent(ir);
-
- inc = new(mem_ctx) ir_expression(ir_unop_neg,
- inc->type,
- inc->clone(mem_ctx, NULL),
- NULL);
- }
-
- return inc;
-}
-
-
-/**
- * Detect whether an if-statement is a loop terminating condition
- *
- * Detects if-statements of the form
- *
- * (if (expression bool ...) (break))
- */
-bool
-is_loop_terminator(ir_if *ir)
-{
- if (!ir->else_instructions.is_empty())
- return false;
-
- ir_instruction *const inst =
- (ir_instruction *) ir->then_instructions.get_head();
- assert(inst != NULL);
-
- if (inst->ir_type != ir_type_loop_jump)
- return false;
-
- ir_loop_jump *const jump = (ir_loop_jump *) inst;
- if (jump->mode != ir_loop_jump::jump_break)
- return false;
-
- return true;
-}
-
-
-loop_state *
-analyze_loop_variables(exec_list *instructions)
-{
- loop_analysis v;
-
- v.run(instructions);
- return v.loops;
-}
+/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "glsl_types.h" +#include "loop_analysis.h" +#include "ir_hierarchical_visitor.h" + +static bool is_loop_terminator(ir_if *ir); + +static bool all_expression_operands_are_loop_constant(ir_rvalue *, + hash_table *); + +static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table *); + + +loop_state::loop_state() +{ + this->ht = hash_table_ctor(0, hash_table_pointer_hash, + hash_table_pointer_compare); + this->mem_ctx = talloc_init("loop state"); + this->loop_found = false; +} + + +loop_state::~loop_state() +{ + hash_table_dtor(this->ht); + talloc_free(this->mem_ctx); +} + + +loop_variable_state * +loop_state::insert(ir_loop *ir) +{ + loop_variable_state *ls = new(this->mem_ctx) loop_variable_state; + + hash_table_insert(this->ht, ls, ir); + this->loop_found = true; + + return ls; +} + + +loop_variable_state * +loop_state::get(const ir_loop *ir) +{ + return (loop_variable_state *) hash_table_find(this->ht, ir); +} + + +loop_variable * +loop_variable_state::get(const ir_variable *ir) +{ + return (loop_variable *) hash_table_find(this->var_hash, ir); +} + + +loop_variable * +loop_variable_state::insert(ir_variable *var) +{ + void *mem_ctx = talloc_parent(this); + loop_variable *lv = talloc_zero(mem_ctx, loop_variable); + + lv->var = var; + + hash_table_insert(this->var_hash, lv, lv->var); + this->variables.push_tail(lv); + + return lv; +} + + +loop_terminator * +loop_variable_state::insert(ir_if *if_stmt) +{ + void *mem_ctx = talloc_parent(this); + loop_terminator *t = talloc_zero(mem_ctx, loop_terminator); + + t->ir = if_stmt; + this->terminators.push_tail(t); + + return t; +} + + +class loop_analysis : public ir_hierarchical_visitor { +public: + loop_analysis(); + + virtual ir_visitor_status visit(ir_loop_jump *); + virtual ir_visitor_status visit(ir_dereference_variable *); + + virtual ir_visitor_status visit_enter(ir_loop *); + virtual ir_visitor_status visit_leave(ir_loop *); + virtual ir_visitor_status visit_enter(ir_assignment *); + virtual ir_visitor_status visit_leave(ir_assignment *); + virtual ir_visitor_status visit_enter(ir_if *); + virtual ir_visitor_status visit_leave(ir_if *); + + loop_state *loops; + + int if_statement_depth; + + ir_assignment *current_assignment; + + exec_list state; +}; + + +loop_analysis::loop_analysis() +{ + this->loops = new loop_state; + + this->if_statement_depth = 0; + this->current_assignment = NULL; +} + + +ir_visitor_status +loop_analysis::visit(ir_loop_jump *ir) +{ + (void) ir; + + assert(!this->state.is_empty()); + + loop_variable_state *const ls = + (loop_variable_state *) this->state.get_head(); + + ls->num_loop_jumps++; + + return visit_continue; +} + + +ir_visitor_status +loop_analysis::visit(ir_dereference_variable *ir) +{ + /* If we're not somewhere inside a loop, there's nothing to do. + */ + if (this->state.is_empty()) + return visit_continue; + + loop_variable_state *const ls = + (loop_variable_state *) this->state.get_head(); + + ir_variable *var = ir->variable_referenced(); + loop_variable *lv = ls->get(var); + + if (lv == NULL) { + lv = ls->insert(var); + lv->read_before_write = !this->in_assignee; + } + + if (this->in_assignee) { + assert(this->current_assignment != NULL); + + lv->conditional_assignment = (this->if_statement_depth > 0) + || (this->current_assignment->condition != NULL); + + if (lv->first_assignment == NULL) { + assert(lv->num_assignments == 0); + + lv->first_assignment = this->current_assignment; + } + + lv->num_assignments++; + } else if (lv->first_assignment == this->current_assignment) { + /* This catches the case where the variable is used in the RHS of an + * assignment where it is also in the LHS. + */ + lv->read_before_write = true; + } + + return visit_continue; +} + +ir_visitor_status +loop_analysis::visit_enter(ir_loop *ir) +{ + loop_variable_state *ls = this->loops->insert(ir); + this->state.push_head(ls); + + return visit_continue; +} + +ir_visitor_status +loop_analysis::visit_leave(ir_loop *ir) +{ + loop_variable_state *const ls = + (loop_variable_state *) this->state.pop_head(); + + + foreach_list(node, &ir->body_instructions) { + /* Skip over declarations at the start of a loop. + */ + if (((ir_instruction *) node)->as_variable()) + continue; + + ir_if *if_stmt = ((ir_instruction *) node)->as_if(); + + if ((if_stmt != NULL) && is_loop_terminator(if_stmt)) + ls->insert(if_stmt); + else + break; + } + + + foreach_list_safe(node, &ls->variables) { + loop_variable *lv = (loop_variable *) node; + + /* Move variables that are already marked as being loop constant to + * a separate list. These trivially don't need to be tested. + */ + if (lv->is_loop_constant()) { + lv->remove(); + ls->constants.push_tail(lv); + } + } + + /* Each variable assigned in the loop that isn't already marked as being loop + * constant might still be loop constant. The requirements at this point + * are: + * + * - Variable is written before it is read. + * + * - Only one assignment to the variable. + * + * - All operands on the RHS of the assignment are also loop constants. + * + * The last requirement is the reason for the progress loop. A variable + * marked as a loop constant on one pass may allow other variables to be + * marked as loop constant on following passes. + */ + bool progress; + do { + progress = false; + + foreach_list_safe(node, &ls->variables) { + loop_variable *lv = (loop_variable *) node; + + if (lv->conditional_assignment || (lv->num_assignments > 1)) + continue; + + /* Process the RHS of the assignment. If all of the variables + * accessed there are loop constants, then add this + */ + ir_rvalue *const rhs = lv->first_assignment->rhs; + if (all_expression_operands_are_loop_constant(rhs, ls->var_hash)) { + lv->rhs_clean = true; + + if (lv->is_loop_constant()) { + progress = true; + + lv->remove(); + ls->constants.push_tail(lv); + } + } + } + } while (progress); + + /* The remaining variables that are not loop invariant might be loop + * induction variables. + */ + foreach_list_safe(node, &ls->variables) { + loop_variable *lv = (loop_variable *) node; + + /* If there is more than one assignment to a variable, it cannot be a + * loop induction variable. This isn't strictly true, but this is a + * very simple induction variable detector, and it can't handle more + * complex cases. + */ + if (lv->num_assignments > 1) + continue; + + /* All of the variables with zero assignments in the loop are loop + * invariant, and they should have already been filtered out. + */ + assert(lv->num_assignments == 1); + assert(lv->first_assignment != NULL); + + /* The assignmnet to the variable in the loop must be unconditional. + */ + if (lv->conditional_assignment) + continue; + + /* Basic loop induction variables have a single assignment in the loop + * that has the form 'VAR = VAR + i' or 'VAR = VAR - i' where i is a + * loop invariant. + */ + ir_rvalue *const inc = + get_basic_induction_increment(lv->first_assignment, ls->var_hash); + if (inc != NULL) { + lv->iv_scale = NULL; + lv->biv = lv->var; + lv->increment = inc; + + lv->remove(); + ls->induction_variables.push_tail(lv); + } + } + + return visit_continue; +} + +ir_visitor_status +loop_analysis::visit_enter(ir_if *ir) +{ + (void) ir; + + if (!this->state.is_empty()) + this->if_statement_depth++; + + return visit_continue; +} + +ir_visitor_status +loop_analysis::visit_leave(ir_if *ir) +{ + (void) ir; + + if (!this->state.is_empty()) + this->if_statement_depth--; + + return visit_continue; +} + +ir_visitor_status +loop_analysis::visit_enter(ir_assignment *ir) +{ + /* If we're not somewhere inside a loop, there's nothing to do. + */ + if (this->state.is_empty()) + return visit_continue_with_parent; + + this->current_assignment = ir; + + return visit_continue; +} + +ir_visitor_status +loop_analysis::visit_leave(ir_assignment *ir) +{ + /* Since the visit_enter exits with visit_continue_with_parent for this + * case, the loop state stack should never be empty here. + */ + assert(!this->state.is_empty()); + + assert(this->current_assignment == ir); + this->current_assignment = NULL; + + return visit_continue; +} + + +class examine_rhs : public ir_hierarchical_visitor { +public: + examine_rhs(hash_table *loop_variables) + { + this->only_uses_loop_constants = true; + this->loop_variables = loop_variables; + } + + virtual ir_visitor_status visit(ir_dereference_variable *ir) + { + loop_variable *lv = + (loop_variable *) hash_table_find(this->loop_variables, ir->var); + + assert(lv != NULL); + + if (lv->is_loop_constant()) { + return visit_continue; + } else { + this->only_uses_loop_constants = false; + return visit_stop; + } + } + + hash_table *loop_variables; + bool only_uses_loop_constants; +}; + + +bool +all_expression_operands_are_loop_constant(ir_rvalue *ir, hash_table *variables) +{ + examine_rhs v(variables); + + ir->accept(&v); + + return v.only_uses_loop_constants; +} + + +ir_rvalue * +get_basic_induction_increment(ir_assignment *ir, hash_table *var_hash) +{ + /* The RHS must be a binary expression. + */ + ir_expression *const rhs = ir->rhs->as_expression(); + if ((rhs == NULL) + || ((rhs->operation != ir_binop_add) + && (rhs->operation != ir_binop_sub))) + return NULL; + + /* One of the of operands of the expression must be the variable assigned. + * If the operation is subtraction, the variable in question must be the + * "left" operand. + */ + ir_variable *const var = ir->lhs->variable_referenced(); + + ir_variable *const op0 = rhs->operands[0]->variable_referenced(); + ir_variable *const op1 = rhs->operands[1]->variable_referenced(); + + if (((op0 != var) && (op1 != var)) + || ((op1 == var) && (rhs->operation == ir_binop_sub))) + return NULL; + + ir_rvalue *inc = (op0 == var) ? rhs->operands[1] : rhs->operands[0]; + + if (inc->as_constant() == NULL) { + ir_variable *const inc_var = inc->variable_referenced(); + if (inc_var != NULL) { + loop_variable *lv = + (loop_variable *) hash_table_find(var_hash, inc_var); + + if (!lv->is_loop_constant()) + inc = NULL; + } else + inc = NULL; + } + + if ((inc != NULL) && (rhs->operation == ir_binop_sub)) { + void *mem_ctx = talloc_parent(ir); + + inc = new(mem_ctx) ir_expression(ir_unop_neg, + inc->type, + inc->clone(mem_ctx, NULL), + NULL); + } + + return inc; +} + + +/** + * Detect whether an if-statement is a loop terminating condition + * + * Detects if-statements of the form + * + * (if (expression bool ...) (break)) + */ +bool +is_loop_terminator(ir_if *ir) +{ + if (!ir->else_instructions.is_empty()) + return false; + + ir_instruction *const inst = + (ir_instruction *) ir->then_instructions.get_head(); + assert(inst != NULL); + + if (inst->ir_type != ir_type_loop_jump) + return false; + + ir_loop_jump *const jump = (ir_loop_jump *) inst; + if (jump->mode != ir_loop_jump::jump_break) + return false; + + return true; +} + + +loop_state * +analyze_loop_variables(exec_list *instructions) +{ + loop_analysis v; + + v.run(instructions); + return v.loops; +} diff --git a/mesalib/src/glsl/loop_analysis.h b/mesalib/src/glsl/loop_analysis.h index 7b0511fbb..229730836 100644 --- a/mesalib/src/glsl/loop_analysis.h +++ b/mesalib/src/glsl/loop_analysis.h @@ -214,6 +214,8 @@ public: loop_variable_state *insert(ir_loop *ir); + bool loop_found; + private: loop_state(); diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 90df5fc9e..fe370fa36 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1,1898 +1,1908 @@ -/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file context.c
- * Mesa context/visual/framebuffer management functions.
- * \author Brian Paul
- */
-
-/**
- * \mainpage Mesa Main Module
- *
- * \section MainIntroduction Introduction
- *
- * The Mesa Main module consists of all the files in the main/ directory.
- * Among the features of this module are:
- * <UL>
- * <LI> Structures to represent most GL state </LI>
- * <LI> State set/get functions </LI>
- * <LI> Display lists </LI>
- * <LI> Texture unit, object and image handling </LI>
- * <LI> Matrix and attribute stacks </LI>
- * </UL>
- *
- * Other modules are responsible for API dispatch, vertex transformation,
- * point/line/triangle setup, rasterization, vertex array caching,
- * vertex/fragment programs/shaders, etc.
- *
- *
- * \section AboutDoxygen About Doxygen
- *
- * If you're viewing this information as Doxygen-generated HTML you'll
- * see the documentation index at the top of this page.
- *
- * The first line lists the Mesa source code modules.
- * The second line lists the indexes available for viewing the documentation
- * for each module.
- *
- * Selecting the <b>Main page</b> link will display a summary of the module
- * (this page).
- *
- * Selecting <b>Data Structures</b> will list all C structures.
- *
- * Selecting the <b>File List</b> link will list all the source files in
- * the module.
- * Selecting a filename will show a list of all functions defined in that file.
- *
- * Selecting the <b>Data Fields</b> link will display a list of all
- * documented structure members.
- *
- * Selecting the <b>Globals</b> link will display a list
- * of all functions, structures, global variables and macros in the module.
- *
- */
-
-
-#include "glheader.h"
-#include "mfeatures.h"
-#include "imports.h"
-#include "accum.h"
-#include "api_exec.h"
-#include "arrayobj.h"
-#include "attrib.h"
-#include "blend.h"
-#include "buffers.h"
-#include "bufferobj.h"
-#include "context.h"
-#include "cpuinfo.h"
-#include "debug.h"
-#include "depth.h"
-#include "dlist.h"
-#include "eval.h"
-#include "extensions.h"
-#include "fbobject.h"
-#include "feedback.h"
-#include "fog.h"
-#include "formats.h"
-#include "framebuffer.h"
-#include "hint.h"
-#include "hash.h"
-#include "light.h"
-#include "lines.h"
-#include "macros.h"
-#include "matrix.h"
-#include "multisample.h"
-#include "pixel.h"
-#include "pixelstore.h"
-#include "points.h"
-#include "polygon.h"
-#include "queryobj.h"
-#include "syncobj.h"
-#include "rastpos.h"
-#include "remap.h"
-#include "scissor.h"
-#include "shared.h"
-#include "shaderobj.h"
-#include "simple_list.h"
-#include "state.h"
-#include "stencil.h"
-#include "texcompress_s3tc.h"
-#include "texstate.h"
-#include "transformfeedback.h"
-#include "mtypes.h"
-#include "varray.h"
-#include "version.h"
-#include "viewport.h"
-#include "vtxfmt.h"
-#include "program/program.h"
-#include "program/prog_print.h"
-#if _HAVE_FULL_GL
-#include "math/m_matrix.h"
-#endif
-#include "main/dispatch.h" /* for _gloffset_COUNT */
-
-#ifdef USE_SPARC_ASM
-#include "sparc/sparc.h"
-#endif
-
-#include "glsl_parser_extras.h"
-#include <stdbool.h>
-
-
-#ifndef MESA_VERBOSE
-int MESA_VERBOSE = 0;
-#endif
-
-#ifndef MESA_DEBUG_FLAGS
-int MESA_DEBUG_FLAGS = 0;
-#endif
-
-
-/* ubyte -> float conversion */
-GLfloat _mesa_ubyte_to_float_color_tab[256];
-
-
-
-/**
- * Swap buffers notification callback.
- *
- * \param ctx GL context.
- *
- * Called by window system just before swapping buffers.
- * We have to finish any pending rendering.
- */
-void
-_mesa_notifySwapBuffers(struct gl_context *ctx)
-{
- if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS)
- _mesa_debug(ctx, "SwapBuffers\n");
- FLUSH_CURRENT( ctx, 0 );
- if (ctx->Driver.Flush) {
- ctx->Driver.Flush(ctx);
- }
-}
-
-
-/**********************************************************************/
-/** \name GL Visual allocation/destruction */
-/**********************************************************************/
-/*@{*/
-
-/**
- * Allocates a struct gl_config structure and initializes it via
- * _mesa_initialize_visual().
- *
- * \param dbFlag double buffering
- * \param stereoFlag stereo buffer
- * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
- * is acceptable but the actual depth type will be GLushort or GLuint as
- * needed.
- * \param stencilBits requested minimum bits per stencil buffer value
- * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
- * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
- * \param redBits number of bits per color component in frame buffer for RGB(A)
- * mode. We always use 8 in core Mesa though.
- * \param greenBits same as above.
- * \param blueBits same as above.
- * \param alphaBits same as above.
- * \param numSamples not really used.
- *
- * \return pointer to new struct gl_config or NULL if requested parameters can't be
- * met.
- *
- * \note Need to add params for level and numAuxBuffers (at least)
- */
-struct gl_config *
-_mesa_create_visual( GLboolean dbFlag,
- GLboolean stereoFlag,
- GLint redBits,
- GLint greenBits,
- GLint blueBits,
- GLint alphaBits,
- GLint depthBits,
- GLint stencilBits,
- GLint accumRedBits,
- GLint accumGreenBits,
- GLint accumBlueBits,
- GLint accumAlphaBits,
- GLint numSamples )
-{
- struct gl_config *vis = CALLOC_STRUCT(gl_config);
- if (vis) {
- if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag,
- redBits, greenBits, blueBits, alphaBits,
- depthBits, stencilBits,
- accumRedBits, accumGreenBits,
- accumBlueBits, accumAlphaBits,
- numSamples)) {
- free(vis);
- return NULL;
- }
- }
- return vis;
-}
-
-
-/**
- * Makes some sanity checks and fills in the fields of the struct
- * gl_config object with the given parameters. If the caller needs to
- * set additional fields, he should just probably init the whole
- * gl_config object himself.
- *
- * \return GL_TRUE on success, or GL_FALSE on failure.
- *
- * \sa _mesa_create_visual() above for the parameter description.
- */
-GLboolean
-_mesa_initialize_visual( struct gl_config *vis,
- GLboolean dbFlag,
- GLboolean stereoFlag,
- GLint redBits,
- GLint greenBits,
- GLint blueBits,
- GLint alphaBits,
- GLint depthBits,
- GLint stencilBits,
- GLint accumRedBits,
- GLint accumGreenBits,
- GLint accumBlueBits,
- GLint accumAlphaBits,
- GLint numSamples )
-{
- assert(vis);
-
- if (depthBits < 0 || depthBits > 32) {
- return GL_FALSE;
- }
- if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
- return GL_FALSE;
- }
- assert(accumRedBits >= 0);
- assert(accumGreenBits >= 0);
- assert(accumBlueBits >= 0);
- assert(accumAlphaBits >= 0);
-
- vis->rgbMode = GL_TRUE;
- vis->doubleBufferMode = dbFlag;
- vis->stereoMode = stereoFlag;
-
- vis->redBits = redBits;
- vis->greenBits = greenBits;
- vis->blueBits = blueBits;
- vis->alphaBits = alphaBits;
- vis->rgbBits = redBits + greenBits + blueBits;
-
- vis->indexBits = 0;
- vis->depthBits = depthBits;
- vis->stencilBits = stencilBits;
-
- vis->accumRedBits = accumRedBits;
- vis->accumGreenBits = accumGreenBits;
- vis->accumBlueBits = accumBlueBits;
- vis->accumAlphaBits = accumAlphaBits;
-
- vis->haveAccumBuffer = accumRedBits > 0;
- vis->haveDepthBuffer = depthBits > 0;
- vis->haveStencilBuffer = stencilBits > 0;
-
- vis->numAuxBuffers = 0;
- vis->level = 0;
- vis->sampleBuffers = numSamples > 0 ? 1 : 0;
- vis->samples = numSamples;
-
- return GL_TRUE;
-}
-
-
-/**
- * Destroy a visual and free its memory.
- *
- * \param vis visual.
- *
- * Frees the visual structure.
- */
-void
-_mesa_destroy_visual( struct gl_config *vis )
-{
- free(vis);
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name Context allocation, initialization, destroying
- *
- * The purpose of the most initialization functions here is to provide the
- * default state values according to the OpenGL specification.
- */
-/**********************************************************************/
-/*@{*/
-
-
-/**
- * This is lame. gdb only seems to recognize enum types that are
- * actually used somewhere. We want to be able to print/use enum
- * values such as TEXTURE_2D_INDEX in gdb. But we don't actually use
- * the gl_texture_index type anywhere. Thus, this lame function.
- */
-static void
-dummy_enum_func(void)
-{
- gl_buffer_index bi = BUFFER_FRONT_LEFT;
- gl_face_index fi = FACE_POS_X;
- gl_frag_attrib fa = FRAG_ATTRIB_WPOS;
- gl_frag_result fr = FRAG_RESULT_DEPTH;
- gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX;
- gl_vert_attrib va = VERT_ATTRIB_POS;
- gl_vert_result vr = VERT_RESULT_HPOS;
- gl_geom_attrib ga = GEOM_ATTRIB_POSITION;
- gl_geom_result gr = GEOM_RESULT_POS;
-
- (void) bi;
- (void) fi;
- (void) fa;
- (void) fr;
- (void) ti;
- (void) va;
- (void) vr;
- (void) ga;
- (void) gr;
-}
-
-
-/**
- * One-time initialization mutex lock.
- *
- * \sa Used by one_time_init().
- */
-_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
-
-
-
-/**
- * Calls all the various one-time-init functions in Mesa.
- *
- * While holding a global mutex lock, calls several initialization functions,
- * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
- * defined.
- *
- * \sa _math_init().
- */
-static void
-one_time_init( struct gl_context *ctx )
-{
- static GLbitfield api_init_mask = 0x0;
-
- _glthread_LOCK_MUTEX(OneTimeLock);
-
- /* truly one-time init */
- if (!api_init_mask) {
- GLuint i;
-
- /* do some implementation tests */
- assert( sizeof(GLbyte) == 1 );
- assert( sizeof(GLubyte) == 1 );
- assert( sizeof(GLshort) == 2 );
- assert( sizeof(GLushort) == 2 );
- assert( sizeof(GLint) == 4 );
- assert( sizeof(GLuint) == 4 );
-
- _mesa_get_cpu_features();
-
- _mesa_init_sqrt_table();
-
- /* context dependence is never a one-time thing... */
- _mesa_init_get_hash(ctx);
-
- for (i = 0; i < 256; i++) {
- _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
- }
-
-#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
- if (MESA_VERBOSE != 0) {
- _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
- MESA_VERSION_STRING, __DATE__, __TIME__);
- }
-#endif
-
-#ifdef DEBUG
- _mesa_test_formats();
-#endif
- }
-
- /* per-API one-time init */
- if (!(api_init_mask & (1 << ctx->API))) {
- /*
- * This is fine as ES does not use the remap table, but it may not be
- * future-proof. We cannot always initialize the remap table because
- * when an app is linked to libGLES*, there are not enough dynamic
- * entries.
- */
- if (ctx->API == API_OPENGL)
- _mesa_init_remap_table();
- }
-
- api_init_mask |= 1 << ctx->API;
-
- _glthread_UNLOCK_MUTEX(OneTimeLock);
-
- /* Hopefully atexit() is widely available. If not, we may need some
- * #ifdef tests here.
- */
- atexit(_mesa_destroy_shader_compiler);
-
- dummy_enum_func();
-}
-
-
-/**
- * Initialize fields of gl_current_attrib (aka ctx->Current.*)
- */
-static void
-_mesa_init_current(struct gl_context *ctx)
-{
- GLuint i;
-
- /* Init all to (0,0,0,1) */
- for (i = 0; i < Elements(ctx->Current.Attrib); i++) {
- ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
- }
-
- /* redo special cases: */
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
-}
-
-
-/**
- * Init vertex/fragment/geometry program limits.
- * Important: drivers should override these with actual limits.
- */
-static void
-init_program_limits(GLenum type, struct gl_program_constants *prog)
-{
- prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS;
- prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS;
- prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS;
- prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS;
- prog->MaxTemps = MAX_PROGRAM_TEMPS;
- prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
- prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
- prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
-
- switch (type) {
- case GL_VERTEX_PROGRAM_ARB:
- prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
- prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
- prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
- break;
- case GL_FRAGMENT_PROGRAM_ARB:
- prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
- prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
- prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
- break;
- case MESA_GEOMETRY_PROGRAM:
- prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
- prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
- prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
-
- prog->MaxGeometryTextureImageUnits = MAX_GEOMETRY_TEXTURE_IMAGE_UNITS;
- prog->MaxGeometryVaryingComponents = MAX_GEOMETRY_VARYING_COMPONENTS;
- prog->MaxVertexVaryingComponents = MAX_VERTEX_VARYING_COMPONENTS;
- prog->MaxGeometryUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS;
- prog->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
- prog->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
- break;
- default:
- assert(0 && "Bad program type in init_program_limits()");
- }
-
- /* Set the native limits to zero. This implies that there is no native
- * support for shaders. Let the drivers fill in the actual values.
- */
- prog->MaxNativeInstructions = 0;
- prog->MaxNativeAluInstructions = 0;
- prog->MaxNativeTexInstructions = 0;
- prog->MaxNativeTexIndirections = 0;
- prog->MaxNativeAttribs = 0;
- prog->MaxNativeTemps = 0;
- prog->MaxNativeAddressRegs = 0;
- prog->MaxNativeParameters = 0;
-}
-
-
-/**
- * Initialize fields of gl_constants (aka ctx->Const.*).
- * Use defaults from config.h. The device drivers will often override
- * some of these values (such as number of texture units).
- */
-static void
-_mesa_init_constants(struct gl_context *ctx)
-{
- assert(ctx);
-
- /* Constants, may be overriden (usually only reduced) by device drivers */
- ctx->Const.MaxTextureMbytes = MAX_TEXTURE_MBYTES;
- ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
- ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
- ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
- ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
- ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
- ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
- ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
- ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
- ctx->Const.MaxTextureImageUnits);
- ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
- ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
- ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
- ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
- ctx->Const.MinPointSize = MIN_POINT_SIZE;
- ctx->Const.MaxPointSize = MAX_POINT_SIZE;
- ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
- ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
- ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
- ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
- ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
- ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
- ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
- ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
- ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
- ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
- ctx->Const.MaxLights = MAX_LIGHTS;
- ctx->Const.MaxShininess = 128.0;
- ctx->Const.MaxSpotExponent = 128.0;
- ctx->Const.MaxViewportWidth = MAX_WIDTH;
- ctx->Const.MaxViewportHeight = MAX_HEIGHT;
-#if FEATURE_ARB_vertex_program
- init_program_limits(GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram);
-#endif
-#if FEATURE_ARB_fragment_program
- init_program_limits(GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram);
-#endif
-#if FEATURE_ARB_geometry_shader4
- init_program_limits(MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram);
-#endif
- ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
- ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
-
- /* CheckArrayBounds is overriden by drivers/x11 for X server */
- ctx->Const.CheckArrayBounds = GL_FALSE;
-
- /* GL_ARB_draw_buffers */
- ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
-
-#if FEATURE_EXT_framebuffer_object
- ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
- ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
-#endif
-
-#if FEATURE_ARB_vertex_shader
- ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
- ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
- ctx->Const.MaxVarying = MAX_VARYING;
-#endif
-
- /* Shading language version */
- if (ctx->API == API_OPENGL) {
- ctx->Const.GLSLVersion = 120;
- }
- else if (ctx->API == API_OPENGLES2) {
- ctx->Const.GLSLVersion = 100;
- }
- else if (ctx->API == API_OPENGLES) {
- ctx->Const.GLSLVersion = 0; /* GLSL not supported */
- }
-
- /* GL_ARB_framebuffer_object */
- ctx->Const.MaxSamples = 0;
-
- /* GL_ARB_sync */
- ctx->Const.MaxServerWaitTimeout = (GLuint64) ~0;
-
- /* GL_ATI_envmap_bumpmap */
- ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
-
- /* GL_EXT_provoking_vertex */
- ctx->Const.QuadsFollowProvokingVertexConvention = GL_TRUE;
-
- /* GL_EXT_transform_feedback */
- ctx->Const.MaxTransformFeedbackSeparateAttribs = MAX_FEEDBACK_ATTRIBS;
- ctx->Const.MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
- ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
-
- /* GL 3.2: hard-coded for now: */
- ctx->Const.ProfileMask = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
-
- /** GL_EXT_gpu_shader4 */
- ctx->Const.MinProgramTexelOffset = -8;
- ctx->Const.MaxProgramTexelOffset = 7;
-}
-
-
-/**
- * Do some sanity checks on the limits/constants for the given context.
- * Only called the first time a context is bound.
- */
-static void
-check_context_limits(struct gl_context *ctx)
-{
- /* check that we don't exceed the size of various bitfields */
- assert(VERT_RESULT_MAX <=
- (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
- assert(FRAG_ATTRIB_MAX <=
- (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
-
- assert(MAX_COMBINED_TEXTURE_IMAGE_UNITS <= 8 * sizeof(GLbitfield));
-
- /* shader-related checks */
- assert(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
- assert(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
-
- assert(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
- assert(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
- assert(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
- assert(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
-
- /* Texture unit checks */
- assert(ctx->Const.MaxTextureImageUnits > 0);
- assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
- assert(ctx->Const.MaxTextureCoordUnits > 0);
- assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
- assert(ctx->Const.MaxTextureUnits > 0);
- assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
- assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
- assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
- ctx->Const.MaxTextureCoordUnits));
- assert(ctx->Const.MaxCombinedTextureImageUnits > 0);
- assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- /* number of coord units cannot be greater than number of image units */
- assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.MaxTextureImageUnits);
-
-
- /* Texture size checks */
- assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS);
- assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS);
- assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS);
- assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE);
-
- /* make sure largest texture image is <= MAX_WIDTH in size */
- assert((1 << (ctx->Const.MaxTextureLevels - 1)) <= MAX_WIDTH);
- assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= MAX_WIDTH);
- assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= MAX_WIDTH);
-
- /* Texture level checks */
- assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
- assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
-
- /* Max texture size should be <= max viewport size (render to texture) */
- assert((1 << (MAX_TEXTURE_LEVELS - 1)) <= MAX_WIDTH);
-
- assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
- assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
-
- assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
-
- /* if this fails, add more enum values to gl_buffer_index */
- assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
-
- /* XXX probably add more tests */
-}
-
-
-/**
- * Initialize the attribute groups in a GL context.
- *
- * \param ctx GL context.
- *
- * Initializes all the attributes, calling the respective <tt>init*</tt>
- * functions for the more complex data structures.
- */
-static GLboolean
-init_attrib_groups(struct gl_context *ctx)
-{
- assert(ctx);
-
- /* Constants */
- _mesa_init_constants( ctx );
-
- /* Extensions */
- _mesa_init_extensions( ctx );
-
- /* Attribute Groups */
- _mesa_init_accum( ctx );
- _mesa_init_attrib( ctx );
- _mesa_init_buffer_objects( ctx );
- _mesa_init_color( ctx );
- _mesa_init_current( ctx );
- _mesa_init_depth( ctx );
- _mesa_init_debug( ctx );
- _mesa_init_display_list( ctx );
- _mesa_init_eval( ctx );
- _mesa_init_fbobjects( ctx );
- _mesa_init_feedback( ctx );
- _mesa_init_fog( ctx );
- _mesa_init_hint( ctx );
- _mesa_init_line( ctx );
- _mesa_init_lighting( ctx );
- _mesa_init_matrix( ctx );
- _mesa_init_multisample( ctx );
- _mesa_init_pixel( ctx );
- _mesa_init_pixelstore( ctx );
- _mesa_init_point( ctx );
- _mesa_init_polygon( ctx );
- _mesa_init_program( ctx );
- _mesa_init_queryobj( ctx );
- _mesa_init_sync( ctx );
- _mesa_init_rastpos( ctx );
- _mesa_init_scissor( ctx );
- _mesa_init_shader_state( ctx );
- _mesa_init_stencil( ctx );
- _mesa_init_transform( ctx );
- _mesa_init_transform_feedback( ctx );
- _mesa_init_varray( ctx );
- _mesa_init_viewport( ctx );
-
- if (!_mesa_init_texture( ctx ))
- return GL_FALSE;
-
- _mesa_init_texture_s3tc( ctx );
-
- /* Miscellaneous */
- ctx->NewState = _NEW_ALL;
- ctx->ErrorValue = (GLenum) GL_NO_ERROR;
- ctx->varying_vp_inputs = ~0;
-
- return GL_TRUE;
-}
-
-
-/**
- * Update default objects in a GL context with respect to shared state.
- *
- * \param ctx GL context.
- *
- * Removes references to old default objects, (texture objects, program
- * objects, etc.) and changes to reference those from the current shared
- * state.
- */
-static GLboolean
-update_default_objects(struct gl_context *ctx)
-{
- assert(ctx);
-
- _mesa_update_default_objects_program(ctx);
- _mesa_update_default_objects_texture(ctx);
- _mesa_update_default_objects_buffer_objects(ctx);
-
- return GL_TRUE;
-}
-
-
-/**
- * This is the default function we plug into all dispatch table slots
- * This helps prevents a segfault when someone calls a GL function without
- * first checking if the extension's supported.
- */
-static int
-generic_nop(void)
-{
- _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)");
- return 0;
-}
-
-
-/**
- * Allocate and initialize a new dispatch table.
- */
-struct _glapi_table *
-_mesa_alloc_dispatch_table(int size)
-{
- /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
- * In practice, this'll be the same for stand-alone Mesa. But for DRI
- * Mesa we do this to accomodate different versions of libGL and various
- * DRI drivers.
- */
- GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
- struct _glapi_table *table;
-
- /* should never happen, but just in case */
- numEntries = MAX2(numEntries, size);
-
- table = (struct _glapi_table *) malloc(numEntries * sizeof(_glapi_proc));
- if (table) {
- _glapi_proc *entry = (_glapi_proc *) table;
- GLint i;
- for (i = 0; i < numEntries; i++) {
- entry[i] = (_glapi_proc) generic_nop;
- }
- }
- return table;
-}
-
-
-/**
- * Initialize a struct gl_context struct (rendering context).
- *
- * This includes allocating all the other structs and arrays which hang off of
- * the context by pointers.
- * Note that the driver needs to pass in its dd_function_table here since
- * we need to at least call driverFunctions->NewTextureObject to create the
- * default texture objects.
- *
- * Called by _mesa_create_context().
- *
- * Performs the imports and exports callback tables initialization, and
- * miscellaneous one-time initializations. If no shared context is supplied one
- * is allocated, and increase its reference count. Setups the GL API dispatch
- * tables. Initialize the TNL module. Sets the maximum Z buffer depth.
- * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
- * for debug flags.
- *
- * \param ctx the context to initialize
- * \param api the GL API type to create the context for
- * \param visual describes the visual attributes for this context
- * \param share_list points to context to share textures, display lists,
- * etc with, or NULL
- * \param driverFunctions table of device driver functions for this context
- * to use
- * \param driverContext pointer to driver-specific context data
- */
-GLboolean
-_mesa_initialize_context_for_api(struct gl_context *ctx,
- gl_api api,
- const struct gl_config *visual,
- struct gl_context *share_list,
- const struct dd_function_table *driverFunctions,
- void *driverContext)
-{
- struct gl_shared_state *shared;
- int i;
-
- /*ASSERT(driverContext);*/
- assert(driverFunctions->NewTextureObject);
- assert(driverFunctions->FreeTexImageData);
-
- ctx->API = api;
- ctx->Visual = *visual;
- ctx->DrawBuffer = NULL;
- ctx->ReadBuffer = NULL;
- ctx->WinSysDrawBuffer = NULL;
- ctx->WinSysReadBuffer = NULL;
-
- /* misc one-time initializations */
- one_time_init(ctx);
-
- /* Plug in driver functions and context pointer here.
- * This is important because when we call alloc_shared_state() below
- * we'll call ctx->Driver.NewTextureObject() to create the default
- * textures.
- */
- ctx->Driver = *driverFunctions;
- ctx->DriverCtx = driverContext;
-
- if (share_list) {
- /* share state with another context */
- shared = share_list->Shared;
- }
- else {
- /* allocate new, unshared state */
- shared = _mesa_alloc_shared_state(ctx);
- if (!shared)
- return GL_FALSE;
- }
-
- _glthread_LOCK_MUTEX(shared->Mutex);
- ctx->Shared = shared;
- shared->RefCount++;
- _glthread_UNLOCK_MUTEX(shared->Mutex);
-
- if (!init_attrib_groups( ctx )) {
- _mesa_release_shared_state(ctx, ctx->Shared);
- return GL_FALSE;
- }
-
-#if FEATURE_dispatch
- /* setup the API dispatch tables */
- switch (ctx->API) {
-#if FEATURE_GL
- case API_OPENGL:
- ctx->Exec = _mesa_create_exec_table();
- break;
-#endif
-#if FEATURE_ES1
- case API_OPENGLES:
- ctx->Exec = _mesa_create_exec_table_es1();
- break;
-#endif
-#if FEATURE_ES2
- case API_OPENGLES2:
- ctx->Exec = _mesa_create_exec_table_es2();
- break;
-#endif
- default:
- _mesa_problem(ctx, "unknown or unsupported API");
- break;
- }
-
- if (!ctx->Exec) {
- _mesa_release_shared_state(ctx, ctx->Shared);
- return GL_FALSE;
- }
-#endif
- ctx->CurrentDispatch = ctx->Exec;
-
- ctx->FragmentProgram._MaintainTexEnvProgram
- = (_mesa_getenv("MESA_TEX_PROG") != NULL);
-
- ctx->VertexProgram._MaintainTnlProgram
- = (_mesa_getenv("MESA_TNL_PROG") != NULL);
- if (ctx->VertexProgram._MaintainTnlProgram) {
- /* this is required... */
- ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
- }
-
- /* Mesa core handles all the formats that mesa core knows about.
- * Drivers will want to override this list with just the formats
- * they can handle, and confirm that appropriate fallbacks exist in
- * _mesa_choose_tex_format().
- */
- memset(&ctx->TextureFormatSupported, GL_TRUE,
- sizeof(ctx->TextureFormatSupported));
-
- switch (ctx->API) {
- case API_OPENGL:
-#if FEATURE_dlist
- ctx->Save = _mesa_create_save_table();
- if (!ctx->Save) {
- _mesa_release_shared_state(ctx, ctx->Shared);
- free(ctx->Exec);
- return GL_FALSE;
- }
-
- _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
-#endif
- break;
- case API_OPENGLES:
- /**
- * GL_OES_texture_cube_map says
- * "Initially all texture generation modes are set to REFLECTION_MAP_OES"
- */
- for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
- texUnit->GenS.Mode = GL_REFLECTION_MAP_NV;
- texUnit->GenT.Mode = GL_REFLECTION_MAP_NV;
- texUnit->GenR.Mode = GL_REFLECTION_MAP_NV;
- texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV;
- texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV;
- texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV;
- }
- break;
- case API_OPENGLES2:
- ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
- ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
- ctx->Point.PointSprite = GL_TRUE; /* always on for ES 2.x */
- break;
- }
-
- ctx->FirstTimeCurrent = GL_TRUE;
-
- return GL_TRUE;
-}
-
-
-/**
- * Initialize an OpenGL context.
- */
-GLboolean
-_mesa_initialize_context(struct gl_context *ctx,
- const struct gl_config *visual,
- struct gl_context *share_list,
- const struct dd_function_table *driverFunctions,
- void *driverContext)
-{
- return _mesa_initialize_context_for_api(ctx,
- API_OPENGL,
- visual,
- share_list,
- driverFunctions,
- driverContext);
-}
-
-
-/**
- * Allocate and initialize a struct gl_context structure.
- * Note that the driver needs to pass in its dd_function_table here since
- * we need to at least call driverFunctions->NewTextureObject to initialize
- * the rendering context.
- *
- * \param api the GL API type to create the context for
- * \param visual a struct gl_config pointer (we copy the struct contents)
- * \param share_list another context to share display lists with or NULL
- * \param driverFunctions points to the dd_function_table into which the
- * driver has plugged in all its special functions.
- * \param driverContext points to the device driver's private context state
- *
- * \return pointer to a new __struct gl_contextRec or NULL if error.
- */
-struct gl_context *
-_mesa_create_context_for_api(gl_api api,
- const struct gl_config *visual,
- struct gl_context *share_list,
- const struct dd_function_table *driverFunctions,
- void *driverContext)
-{
- struct gl_context *ctx;
-
- ASSERT(visual);
- /*ASSERT(driverContext);*/
-
- ctx = (struct gl_context *) calloc(1, sizeof(struct gl_context));
- if (!ctx)
- return NULL;
-
- if (_mesa_initialize_context_for_api(ctx, api, visual, share_list,
- driverFunctions, driverContext)) {
- return ctx;
- }
- else {
- free(ctx);
- return NULL;
- }
-}
-
-
-/**
- * Create an OpenGL context.
- */
-struct gl_context *
-_mesa_create_context(const struct gl_config *visual,
- struct gl_context *share_list,
- const struct dd_function_table *driverFunctions,
- void *driverContext)
-{
- return _mesa_create_context_for_api(API_OPENGL, visual,
- share_list,
- driverFunctions,
- driverContext);
-}
-
-
-/**
- * Free the data associated with the given context.
- *
- * But doesn't free the struct gl_context struct itself.
- *
- * \sa _mesa_initialize_context() and init_attrib_groups().
- */
-void
-_mesa_free_context_data( struct gl_context *ctx )
-{
- if (!_mesa_get_current_context()){
- /* No current context, but we may need one in order to delete
- * texture objs, etc. So temporarily bind the context now.
- */
- _mesa_make_current(ctx, NULL, NULL);
- }
-
- /* unreference WinSysDraw/Read buffers */
- _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
- _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
- _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
- _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);
-
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
-
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
-
- _mesa_free_attrib_data(ctx);
- _mesa_free_buffer_objects(ctx);
- _mesa_free_lighting_data( ctx );
- _mesa_free_eval_data( ctx );
- _mesa_free_texture_data( ctx );
- _mesa_free_matrix_data( ctx );
- _mesa_free_viewport_data( ctx );
- _mesa_free_program_data(ctx);
- _mesa_free_shader_state(ctx);
- _mesa_free_queryobj_data(ctx);
- _mesa_free_sync_data(ctx);
- _mesa_free_varray_data(ctx);
- _mesa_free_transform_feedback(ctx);
-
- _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
-
-#if FEATURE_ARB_pixel_buffer_object
- _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
-#endif
-
-#if FEATURE_ARB_vertex_buffer_object
- _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj, NULL);
-#endif
-
- /* free dispatch tables */
- free(ctx->Exec);
- free(ctx->Save);
-
- /* Shared context state (display lists, textures, etc) */
- _mesa_release_shared_state( ctx, ctx->Shared );
-
- /* needs to be after freeing shared state */
- _mesa_free_display_list_data(ctx);
-
- if (ctx->Extensions.String)
- free((void *) ctx->Extensions.String);
-
- if (ctx->VersionString)
- free(ctx->VersionString);
-
- /* unbind the context if it's currently bound */
- if (ctx == _mesa_get_current_context()) {
- _mesa_make_current(NULL, NULL, NULL);
- }
-}
-
-
-/**
- * Destroy a struct gl_context structure.
- *
- * \param ctx GL context.
- *
- * Calls _mesa_free_context_data() and frees the gl_context object itself.
- */
-void
-_mesa_destroy_context( struct gl_context *ctx )
-{
- if (ctx) {
- _mesa_free_context_data(ctx);
- free( (void *) ctx );
- }
-}
-
-
-#if _HAVE_FULL_GL
-/**
- * Copy attribute groups from one context to another.
- *
- * \param src source context
- * \param dst destination context
- * \param mask bitwise OR of GL_*_BIT flags
- *
- * According to the bits specified in \p mask, copies the corresponding
- * attributes from \p src into \p dst. For many of the attributes a simple \c
- * memcpy is not enough due to the existence of internal pointers in their data
- * structures.
- */
-void
-_mesa_copy_context( const struct gl_context *src, struct gl_context *dst, GLuint mask )
-{
- if (mask & GL_ACCUM_BUFFER_BIT) {
- /* OK to memcpy */
- dst->Accum = src->Accum;
- }
- if (mask & GL_COLOR_BUFFER_BIT) {
- /* OK to memcpy */
- dst->Color = src->Color;
- }
- if (mask & GL_CURRENT_BIT) {
- /* OK to memcpy */
- dst->Current = src->Current;
- }
- if (mask & GL_DEPTH_BUFFER_BIT) {
- /* OK to memcpy */
- dst->Depth = src->Depth;
- }
- if (mask & GL_ENABLE_BIT) {
- /* no op */
- }
- if (mask & GL_EVAL_BIT) {
- /* OK to memcpy */
- dst->Eval = src->Eval;
- }
- if (mask & GL_FOG_BIT) {
- /* OK to memcpy */
- dst->Fog = src->Fog;
- }
- if (mask & GL_HINT_BIT) {
- /* OK to memcpy */
- dst->Hint = src->Hint;
- }
- if (mask & GL_LIGHTING_BIT) {
- GLuint i;
- /* begin with memcpy */
- dst->Light = src->Light;
- /* fixup linked lists to prevent pointer insanity */
- make_empty_list( &(dst->Light.EnabledList) );
- for (i = 0; i < MAX_LIGHTS; i++) {
- if (dst->Light.Light[i].Enabled) {
- insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
- }
- }
- }
- if (mask & GL_LINE_BIT) {
- /* OK to memcpy */
- dst->Line = src->Line;
- }
- if (mask & GL_LIST_BIT) {
- /* OK to memcpy */
- dst->List = src->List;
- }
- if (mask & GL_PIXEL_MODE_BIT) {
- /* OK to memcpy */
- dst->Pixel = src->Pixel;
- }
- if (mask & GL_POINT_BIT) {
- /* OK to memcpy */
- dst->Point = src->Point;
- }
- if (mask & GL_POLYGON_BIT) {
- /* OK to memcpy */
- dst->Polygon = src->Polygon;
- }
- if (mask & GL_POLYGON_STIPPLE_BIT) {
- /* Use loop instead of memcpy due to problem with Portland Group's
- * C compiler. Reported by John Stone.
- */
- GLuint i;
- for (i = 0; i < 32; i++) {
- dst->PolygonStipple[i] = src->PolygonStipple[i];
- }
- }
- if (mask & GL_SCISSOR_BIT) {
- /* OK to memcpy */
- dst->Scissor = src->Scissor;
- }
- if (mask & GL_STENCIL_BUFFER_BIT) {
- /* OK to memcpy */
- dst->Stencil = src->Stencil;
- }
- if (mask & GL_TEXTURE_BIT) {
- /* Cannot memcpy because of pointers */
- _mesa_copy_texture_state(src, dst);
- }
- if (mask & GL_TRANSFORM_BIT) {
- /* OK to memcpy */
- dst->Transform = src->Transform;
- }
- if (mask & GL_VIEWPORT_BIT) {
- /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
- dst->Viewport.X = src->Viewport.X;
- dst->Viewport.Y = src->Viewport.Y;
- dst->Viewport.Width = src->Viewport.Width;
- dst->Viewport.Height = src->Viewport.Height;
- dst->Viewport.Near = src->Viewport.Near;
- dst->Viewport.Far = src->Viewport.Far;
- _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
- }
-
- /* XXX FIXME: Call callbacks?
- */
- dst->NewState = _NEW_ALL;
-}
-#endif
-
-
-/**
- * Check if the given context can render into the given framebuffer
- * by checking visual attributes.
- *
- * Most of these tests could go away because Mesa is now pretty flexible
- * in terms of mixing rendering contexts with framebuffers. As long
- * as RGB vs. CI mode agree, we're probably good.
- *
- * \return GL_TRUE if compatible, GL_FALSE otherwise.
- */
-static GLboolean
-check_compatible(const struct gl_context *ctx,
- const struct gl_framebuffer *buffer)
-{
- const struct gl_config *ctxvis = &ctx->Visual;
- const struct gl_config *bufvis = &buffer->Visual;
-
- if (buffer == _mesa_get_incomplete_framebuffer())
- return GL_TRUE;
-
-#if 0
- /* disabling this fixes the fgl_glxgears pbuffer demo */
- if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
- return GL_FALSE;
-#endif
- if (ctxvis->stereoMode && !bufvis->stereoMode)
- return GL_FALSE;
- if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
- return GL_FALSE;
- if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
- return GL_FALSE;
- if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
- return GL_FALSE;
- if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
- return GL_FALSE;
- if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
- return GL_FALSE;
- if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
- return GL_FALSE;
-#if 0
- /* disabled (see bug 11161) */
- if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
- return GL_FALSE;
-#endif
- if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-
-/**
- * Do one-time initialization for the given framebuffer. Specifically,
- * ask the driver for the window's current size and update the framebuffer
- * object to match.
- * Really, the device driver should totally take care of this.
- */
-static void
-initialize_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
- GLuint width, height;
- if (ctx->Driver.GetBufferSize) {
- ctx->Driver.GetBufferSize(fb, &width, &height);
- if (ctx->Driver.ResizeBuffers)
- ctx->Driver.ResizeBuffers(ctx, fb, width, height);
- fb->Initialized = GL_TRUE;
- }
-}
-
-
-/**
- * Check if the viewport/scissor size has not yet been initialized.
- * Initialize the size if the given width and height are non-zero.
- */
-void
-_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
-{
- if (!ctx->ViewportInitialized && width > 0 && height > 0) {
- /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
- * potential infinite recursion.
- */
- ctx->ViewportInitialized = GL_TRUE;
- _mesa_set_viewport(ctx, 0, 0, width, height);
- _mesa_set_scissor(ctx, 0, 0, width, height);
- }
-}
-
-
-/**
- * Bind the given context to the given drawBuffer and readBuffer and
- * make it the current context for the calling thread.
- * We'll render into the drawBuffer and read pixels from the
- * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
- *
- * We check that the context's and framebuffer's visuals are compatible
- * and return immediately if they're not.
- *
- * \param newCtx the new GL context. If NULL then there will be no current GL
- * context.
- * \param drawBuffer the drawing framebuffer
- * \param readBuffer the reading framebuffer
- */
-GLboolean
-_mesa_make_current( struct gl_context *newCtx,
- struct gl_framebuffer *drawBuffer,
- struct gl_framebuffer *readBuffer )
-{
- GET_CURRENT_CONTEXT(curCtx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(newCtx, "_mesa_make_current()\n");
-
- /* Check that the context's and framebuffer's visuals are compatible.
- */
- if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
- if (!check_compatible(newCtx, drawBuffer)) {
- _mesa_warning(newCtx,
- "MakeCurrent: incompatible visuals for context and drawbuffer");
- return GL_FALSE;
- }
- }
- if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
- if (!check_compatible(newCtx, readBuffer)) {
- _mesa_warning(newCtx,
- "MakeCurrent: incompatible visuals for context and readbuffer");
- return GL_FALSE;
- }
- }
-
- if (curCtx &&
- (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */
- curCtx != newCtx)
- _mesa_flush(curCtx);
-
- /* We used to call _glapi_check_multithread() here. Now do it in drivers */
- _glapi_set_context((void *) newCtx);
- ASSERT(_mesa_get_current_context() == newCtx);
-
- if (!newCtx) {
- _glapi_set_dispatch(NULL); /* none current */
- }
- else {
- _glapi_set_dispatch(newCtx->CurrentDispatch);
-
- if (drawBuffer && readBuffer) {
- /* TODO: check if newCtx and buffer's visual match??? */
-
- ASSERT(drawBuffer->Name == 0);
- ASSERT(readBuffer->Name == 0);
- _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
- _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
-
- /*
- * Only set the context's Draw/ReadBuffer fields if they're NULL
- * or not bound to a user-created FBO.
- */
- if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
- /* KW: merge conflict here, revisit.
- */
- /* fix up the fb fields - these will end up wrong otherwise
- * if the DRIdrawable changes, and everything relies on them.
- * This is a bit messy (same as needed in _mesa_BindFramebufferEXT)
- */
- unsigned int i;
- GLenum buffers[MAX_DRAW_BUFFERS];
-
- _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
-
- for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) {
- buffers[i] = newCtx->Color.DrawBuffer[i];
- }
-
- _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers,
- buffers, NULL);
- }
- if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
- _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
- }
-
- /* XXX only set this flag if we're really changing the draw/read
- * framebuffer bindings.
- */
- newCtx->NewState |= _NEW_BUFFERS;
-
-#if 1
- /* We want to get rid of these lines: */
-
-#if _HAVE_FULL_GL
- if (!drawBuffer->Initialized) {
- initialize_framebuffer_size(newCtx, drawBuffer);
- }
- if (readBuffer != drawBuffer && !readBuffer->Initialized) {
- initialize_framebuffer_size(newCtx, readBuffer);
- }
-
- _mesa_resizebuffers(newCtx);
-#endif
-
-#else
- /* We want the drawBuffer and readBuffer to be initialized by
- * the driver.
- * This generally means the Width and Height match the actual
- * window size and the renderbuffers (both hardware and software
- * based) are allocated to match. The later can generally be
- * done with a call to _mesa_resize_framebuffer().
- *
- * It's theoretically possible for a buffer to have zero width
- * or height, but for now, assert check that the driver did what's
- * expected of it.
- */
- ASSERT(drawBuffer->Width > 0);
- ASSERT(drawBuffer->Height > 0);
-#endif
-
- if (drawBuffer) {
- _mesa_check_init_viewport(newCtx,
- drawBuffer->Width, drawBuffer->Height);
- }
- }
-
- if (newCtx->FirstTimeCurrent) {
- _mesa_compute_version(newCtx);
-
- newCtx->Extensions.String = _mesa_make_extension_string(newCtx);
-
- check_context_limits(newCtx);
-
- /* We can use this to help debug user's problems. Tell them to set
- * the MESA_INFO env variable before running their app. Then the
- * first time each context is made current we'll print some useful
- * information.
- */
- if (_mesa_getenv("MESA_INFO")) {
- _mesa_print_info();
- }
-
- newCtx->FirstTimeCurrent = GL_FALSE;
- }
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Make context 'ctx' share the display lists, textures and programs
- * that are associated with 'ctxToShare'.
- * Any display lists, textures or programs associated with 'ctx' will
- * be deleted if nobody else is sharing them.
- */
-GLboolean
-_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
-{
- if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
- struct gl_shared_state *oldSharedState = ctx->Shared;
-
- ctx->Shared = ctxToShare->Shared;
-
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- ctx->Shared->RefCount++;
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
-
- update_default_objects(ctx);
-
- _mesa_release_shared_state(ctx, oldSharedState);
-
- return GL_TRUE;
- }
- else {
- return GL_FALSE;
- }
-}
-
-
-
-/**
- * \return pointer to the current GL context for this thread.
- *
- * Calls _glapi_get_context(). This isn't the fastest way to get the current
- * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in
- * context.h.
- */
-struct gl_context *
-_mesa_get_current_context( void )
-{
- return (struct gl_context *) _glapi_get_context();
-}
-
-
-/**
- * Get context's current API dispatch table.
- *
- * It'll either be the immediate-mode execute dispatcher or the display list
- * compile dispatcher.
- *
- * \param ctx GL context.
- *
- * \return pointer to dispatch_table.
- *
- * Simply returns __struct gl_contextRec::CurrentDispatch.
- */
-struct _glapi_table *
-_mesa_get_dispatch(struct gl_context *ctx)
-{
- return ctx->CurrentDispatch;
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name Miscellaneous functions */
-/**********************************************************************/
-/*@{*/
-
-/**
- * Record an error.
- *
- * \param ctx GL context.
- * \param error error code.
- *
- * Records the given error code and call the driver's dd_function_table::Error
- * function if defined.
- *
- * \sa
- * This is called via _mesa_error().
- */
-void
-_mesa_record_error(struct gl_context *ctx, GLenum error)
-{
- if (!ctx)
- return;
-
- if (ctx->ErrorValue == GL_NO_ERROR) {
- ctx->ErrorValue = error;
- }
-
- /* Call device driver's error handler, if any. This is used on the Mac. */
- if (ctx->Driver.Error) {
- ctx->Driver.Error(ctx);
- }
-}
-
-
-/**
- * Flush commands and wait for completion.
- */
-void
-_mesa_finish(struct gl_context *ctx)
-{
- FLUSH_CURRENT( ctx, 0 );
- if (ctx->Driver.Finish) {
- ctx->Driver.Finish(ctx);
- }
-}
-
-
-/**
- * Flush commands.
- */
-void
-_mesa_flush(struct gl_context *ctx)
-{
- FLUSH_CURRENT( ctx, 0 );
- if (ctx->Driver.Flush) {
- ctx->Driver.Flush(ctx);
- }
-}
-
-
-
-/**
- * Execute glFinish().
- *
- * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
- * dd_function_table::Finish driver callback, if not NULL.
- */
-void GLAPIENTRY
-_mesa_Finish(void)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- _mesa_finish(ctx);
-}
-
-
-/**
- * Execute glFlush().
- *
- * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
- * dd_function_table::Flush driver callback, if not NULL.
- */
-void GLAPIENTRY
-_mesa_Flush(void)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- _mesa_flush(ctx);
-}
-
-
-/**
- * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over
- * MUL/MAD, or vice versa, call this function to register that.
- * Otherwise we default to MUL/MAD.
- */
-void
-_mesa_set_mvp_with_dp4( struct gl_context *ctx,
- GLboolean flag )
-{
- ctx->mvp_with_dp4 = flag;
-}
-
-
-
-/**
- * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
- * is called to see if it's valid to render. This involves checking that
- * the current shader is valid and the framebuffer is complete.
- * If an error is detected it'll be recorded here.
- * \return GL_TRUE if OK to render, GL_FALSE if not
- */
-GLboolean
-_mesa_valid_to_render(struct gl_context *ctx, const char *where)
-{
- bool vert_from_glsl_shader = false;
- bool geom_from_glsl_shader = false;
- bool frag_from_glsl_shader = false;
-
- /* This depends on having up to date derived state (shaders) */
- if (ctx->NewState)
- _mesa_update_state(ctx);
-
- if (ctx->Shader.CurrentVertexProgram) {
- vert_from_glsl_shader = true;
-
- if (!ctx->Shader.CurrentVertexProgram->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(shader not linked)", where);
- return GL_FALSE;
- }
-#if 0 /* not normally enabled */
- {
- char errMsg[100];
- if (!_mesa_validate_shader_program(ctx,
- ctx->Shader.CurrentVertexProgram,
- errMsg)) {
- _mesa_warning(ctx, "Shader program %u is invalid: %s",
- ctx->Shader.CurrentVertexProgram->Name, errMsg);
- }
- }
-#endif
- }
-
- if (ctx->Shader.CurrentGeometryProgram) {
- geom_from_glsl_shader = true;
-
- if (!ctx->Shader.CurrentGeometryProgram->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(shader not linked)", where);
- return GL_FALSE;
- }
-#if 0 /* not normally enabled */
- {
- char errMsg[100];
- if (!_mesa_validate_shader_program(ctx,
- ctx->Shader.CurrentGeometryProgram,
- errMsg)) {
- _mesa_warning(ctx, "Shader program %u is invalid: %s",
- ctx->Shader.CurrentGeometryProgram->Name, errMsg);
- }
- }
-#endif
- }
-
- if (ctx->Shader.CurrentFragmentProgram) {
- frag_from_glsl_shader = true;
-
- if (!ctx->Shader.CurrentFragmentProgram->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(shader not linked)", where);
- return GL_FALSE;
- }
-#if 0 /* not normally enabled */
- {
- char errMsg[100];
- if (!_mesa_validate_shader_program(ctx,
- ctx->Shader.CurrentFragmentProgram,
- errMsg)) {
- _mesa_warning(ctx, "Shader program %u is invalid: %s",
- ctx->Shader.CurrentFragmentProgram->Name, errMsg);
- }
- }
-#endif
- }
-
- /* Any shader stages that are not supplied by the GLSL shader and have
- * assembly shaders enabled must now be validated.
- */
- if (!vert_from_glsl_shader
- && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(vertex program not valid)", where);
- return GL_FALSE;
- }
-
- /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current
- * FINISHME: geometry program should validated here.
- */
- (void) geom_from_glsl_shader;
-
- if (!frag_from_glsl_shader) {
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(fragment program not valid)", where);
- return GL_FALSE;
- }
-
- /* If drawing to integer-valued color buffers, there must be an
- * active fragment shader (GL_EXT_texture_integer).
- */
- if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(integer format but no fragment shader)", where);
- return GL_FALSE;
- }
- }
-
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "%s(incomplete framebuffer)", where);
- return GL_FALSE;
- }
-
-#ifdef DEBUG
- if (ctx->Shader.Flags & GLSL_LOG) {
- struct gl_shader_program *shProg[MESA_SHADER_TYPES];
- gl_shader_type i;
-
- shProg[MESA_SHADER_VERTEX] = ctx->Shader.CurrentVertexProgram;
- shProg[MESA_SHADER_GEOMETRY] = ctx->Shader.CurrentGeometryProgram;
- shProg[MESA_SHADER_FRAGMENT] = ctx->Shader.CurrentFragmentProgram;
-
- for (i = 0; i < MESA_SHADER_TYPES; i++) {
- struct gl_shader *sh;
-
- if (shProg[i] == NULL || shProg[i]->_Used
- || shProg[i]->_LinkedShaders[i] == NULL)
- continue;
-
- /* This is the first time this shader is being used.
- * Append shader's constants/uniforms to log file.
- *
- * The logic is a little odd here. We only want to log data for each
- * shader target that will actually be used, and we only want to log
- * it once. It's possible to have a program bound to the vertex
- * shader target that also supplied a fragment shader. If that
- * program isn't also bound to the fragment shader target we don't
- * want to log its fragment data.
- */
- sh = shProg[i]->_LinkedShaders[i];
- switch (sh->Type) {
- case GL_VERTEX_SHADER:
- _mesa_append_uniforms_to_file(sh, &shProg[i]->VertexProgram->Base);
- break;
-
- case GL_GEOMETRY_SHADER_ARB:
- _mesa_append_uniforms_to_file(sh,
- &shProg[i]->GeometryProgram->Base);
- break;
-
- case GL_FRAGMENT_SHADER:
- _mesa_append_uniforms_to_file(sh,
- &shProg[i]->FragmentProgram->Base);
- break;
- }
- }
-
- for (i = 0; i < MESA_SHADER_TYPES; i++) {
- if (shProg[i] != NULL)
- shProg[i]->_Used = GL_TRUE;
- }
- }
-#endif
-
- return GL_TRUE;
-}
-
-
-/*@}*/
+/* + * Mesa 3-D graphics library + * Version: 7.3 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright (C) 2008 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file context.c + * Mesa context/visual/framebuffer management functions. + * \author Brian Paul + */ + +/** + * \mainpage Mesa Main Module + * + * \section MainIntroduction Introduction + * + * The Mesa Main module consists of all the files in the main/ directory. + * Among the features of this module are: + * <UL> + * <LI> Structures to represent most GL state </LI> + * <LI> State set/get functions </LI> + * <LI> Display lists </LI> + * <LI> Texture unit, object and image handling </LI> + * <LI> Matrix and attribute stacks </LI> + * </UL> + * + * Other modules are responsible for API dispatch, vertex transformation, + * point/line/triangle setup, rasterization, vertex array caching, + * vertex/fragment programs/shaders, etc. + * + * + * \section AboutDoxygen About Doxygen + * + * If you're viewing this information as Doxygen-generated HTML you'll + * see the documentation index at the top of this page. + * + * The first line lists the Mesa source code modules. + * The second line lists the indexes available for viewing the documentation + * for each module. + * + * Selecting the <b>Main page</b> link will display a summary of the module + * (this page). + * + * Selecting <b>Data Structures</b> will list all C structures. + * + * Selecting the <b>File List</b> link will list all the source files in + * the module. + * Selecting a filename will show a list of all functions defined in that file. + * + * Selecting the <b>Data Fields</b> link will display a list of all + * documented structure members. + * + * Selecting the <b>Globals</b> link will display a list + * of all functions, structures, global variables and macros in the module. + * + */ + + +#include "glheader.h" +#include "mfeatures.h" +#include "imports.h" +#include "accum.h" +#include "api_exec.h" +#include "arrayobj.h" +#include "attrib.h" +#include "blend.h" +#include "buffers.h" +#include "bufferobj.h" +#include "context.h" +#include "cpuinfo.h" +#include "debug.h" +#include "depth.h" +#include "dlist.h" +#include "eval.h" +#include "extensions.h" +#include "fbobject.h" +#include "feedback.h" +#include "fog.h" +#include "formats.h" +#include "framebuffer.h" +#include "hint.h" +#include "hash.h" +#include "light.h" +#include "lines.h" +#include "macros.h" +#include "matrix.h" +#include "multisample.h" +#include "pixel.h" +#include "pixelstore.h" +#include "points.h" +#include "polygon.h" +#include "queryobj.h" +#include "syncobj.h" +#include "rastpos.h" +#include "remap.h" +#include "scissor.h" +#include "shared.h" +#include "shaderobj.h" +#include "simple_list.h" +#include "state.h" +#include "stencil.h" +#include "texcompress_s3tc.h" +#include "texstate.h" +#include "transformfeedback.h" +#include "mtypes.h" +#include "varray.h" +#include "version.h" +#include "viewport.h" +#include "vtxfmt.h" +#include "program/program.h" +#include "program/prog_print.h" +#if _HAVE_FULL_GL +#include "math/m_matrix.h" +#endif +#include "main/dispatch.h" /* for _gloffset_COUNT */ + +#ifdef USE_SPARC_ASM +#include "sparc/sparc.h" +#endif + +#include "glsl_parser_extras.h" +#include <stdbool.h> + + +#ifndef MESA_VERBOSE +int MESA_VERBOSE = 0; +#endif + +#ifndef MESA_DEBUG_FLAGS +int MESA_DEBUG_FLAGS = 0; +#endif + + +/* ubyte -> float conversion */ +GLfloat _mesa_ubyte_to_float_color_tab[256]; + + + +/** + * Swap buffers notification callback. + * + * \param ctx GL context. + * + * Called by window system just before swapping buffers. + * We have to finish any pending rendering. + */ +void +_mesa_notifySwapBuffers(struct gl_context *ctx) +{ + if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS) + _mesa_debug(ctx, "SwapBuffers\n"); + FLUSH_CURRENT( ctx, 0 ); + if (ctx->Driver.Flush) { + ctx->Driver.Flush(ctx); + } +} + + +/**********************************************************************/ +/** \name GL Visual allocation/destruction */ +/**********************************************************************/ +/*@{*/ + +/** + * Allocates a struct gl_config structure and initializes it via + * _mesa_initialize_visual(). + * + * \param dbFlag double buffering + * \param stereoFlag stereo buffer + * \param depthBits requested bits per depth buffer value. Any value in [0, 32] + * is acceptable but the actual depth type will be GLushort or GLuint as + * needed. + * \param stencilBits requested minimum bits per stencil buffer value + * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer. + * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE + * \param redBits number of bits per color component in frame buffer for RGB(A) + * mode. We always use 8 in core Mesa though. + * \param greenBits same as above. + * \param blueBits same as above. + * \param alphaBits same as above. + * \param numSamples not really used. + * + * \return pointer to new struct gl_config or NULL if requested parameters can't be + * met. + * + * \note Need to add params for level and numAuxBuffers (at least) + */ +struct gl_config * +_mesa_create_visual( GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ) +{ + struct gl_config *vis = CALLOC_STRUCT(gl_config); + if (vis) { + if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag, + redBits, greenBits, blueBits, alphaBits, + depthBits, stencilBits, + accumRedBits, accumGreenBits, + accumBlueBits, accumAlphaBits, + numSamples)) { + free(vis); + return NULL; + } + } + return vis; +} + + +/** + * Makes some sanity checks and fills in the fields of the struct + * gl_config object with the given parameters. If the caller needs to + * set additional fields, he should just probably init the whole + * gl_config object himself. + * + * \return GL_TRUE on success, or GL_FALSE on failure. + * + * \sa _mesa_create_visual() above for the parameter description. + */ +GLboolean +_mesa_initialize_visual( struct gl_config *vis, + GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ) +{ + assert(vis); + + if (depthBits < 0 || depthBits > 32) { + return GL_FALSE; + } + if (stencilBits < 0 || stencilBits > STENCIL_BITS) { + return GL_FALSE; + } + assert(accumRedBits >= 0); + assert(accumGreenBits >= 0); + assert(accumBlueBits >= 0); + assert(accumAlphaBits >= 0); + + vis->rgbMode = GL_TRUE; + vis->doubleBufferMode = dbFlag; + vis->stereoMode = stereoFlag; + + vis->redBits = redBits; + vis->greenBits = greenBits; + vis->blueBits = blueBits; + vis->alphaBits = alphaBits; + vis->rgbBits = redBits + greenBits + blueBits; + + vis->indexBits = 0; + vis->depthBits = depthBits; + vis->stencilBits = stencilBits; + + vis->accumRedBits = accumRedBits; + vis->accumGreenBits = accumGreenBits; + vis->accumBlueBits = accumBlueBits; + vis->accumAlphaBits = accumAlphaBits; + + vis->haveAccumBuffer = accumRedBits > 0; + vis->haveDepthBuffer = depthBits > 0; + vis->haveStencilBuffer = stencilBits > 0; + + vis->numAuxBuffers = 0; + vis->level = 0; + vis->sampleBuffers = numSamples > 0 ? 1 : 0; + vis->samples = numSamples; + + return GL_TRUE; +} + + +/** + * Destroy a visual and free its memory. + * + * \param vis visual. + * + * Frees the visual structure. + */ +void +_mesa_destroy_visual( struct gl_config *vis ) +{ + free(vis); +} + +/*@}*/ + + +/**********************************************************************/ +/** \name Context allocation, initialization, destroying + * + * The purpose of the most initialization functions here is to provide the + * default state values according to the OpenGL specification. + */ +/**********************************************************************/ +/*@{*/ + + +/** + * This is lame. gdb only seems to recognize enum types that are + * actually used somewhere. We want to be able to print/use enum + * values such as TEXTURE_2D_INDEX in gdb. But we don't actually use + * the gl_texture_index type anywhere. Thus, this lame function. + */ +static void +dummy_enum_func(void) +{ + gl_buffer_index bi = BUFFER_FRONT_LEFT; + gl_face_index fi = FACE_POS_X; + gl_frag_attrib fa = FRAG_ATTRIB_WPOS; + gl_frag_result fr = FRAG_RESULT_DEPTH; + gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX; + gl_vert_attrib va = VERT_ATTRIB_POS; + gl_vert_result vr = VERT_RESULT_HPOS; + gl_geom_attrib ga = GEOM_ATTRIB_POSITION; + gl_geom_result gr = GEOM_RESULT_POS; + + (void) bi; + (void) fi; + (void) fa; + (void) fr; + (void) ti; + (void) va; + (void) vr; + (void) ga; + (void) gr; +} + + +/** + * One-time initialization mutex lock. + * + * \sa Used by one_time_init(). + */ +_glthread_DECLARE_STATIC_MUTEX(OneTimeLock); + + + +/** + * Calls all the various one-time-init functions in Mesa. + * + * While holding a global mutex lock, calls several initialization functions, + * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is + * defined. + * + * \sa _math_init(). + */ +static void +one_time_init( struct gl_context *ctx ) +{ + static GLbitfield api_init_mask = 0x0; + + _glthread_LOCK_MUTEX(OneTimeLock); + + /* truly one-time init */ + if (!api_init_mask) { + GLuint i; + + /* do some implementation tests */ + assert( sizeof(GLbyte) == 1 ); + assert( sizeof(GLubyte) == 1 ); + assert( sizeof(GLshort) == 2 ); + assert( sizeof(GLushort) == 2 ); + assert( sizeof(GLint) == 4 ); + assert( sizeof(GLuint) == 4 ); + + _mesa_get_cpu_features(); + + _mesa_init_sqrt_table(); + + /* context dependence is never a one-time thing... */ + _mesa_init_get_hash(ctx); + + for (i = 0; i < 256; i++) { + _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; + } + +#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) + if (MESA_VERBOSE != 0) { + _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", + MESA_VERSION_STRING, __DATE__, __TIME__); + } +#endif + +#ifdef DEBUG + _mesa_test_formats(); +#endif + } + + /* per-API one-time init */ + if (!(api_init_mask & (1 << ctx->API))) { + /* + * This is fine as ES does not use the remap table, but it may not be + * future-proof. We cannot always initialize the remap table because + * when an app is linked to libGLES*, there are not enough dynamic + * entries. + */ + if (ctx->API == API_OPENGL) + _mesa_init_remap_table(); + } + + api_init_mask |= 1 << ctx->API; + + _glthread_UNLOCK_MUTEX(OneTimeLock); + + /* Hopefully atexit() is widely available. If not, we may need some + * #ifdef tests here. + */ + atexit(_mesa_destroy_shader_compiler); + + dummy_enum_func(); +} + + +/** + * Initialize fields of gl_current_attrib (aka ctx->Current.*) + */ +static void +_mesa_init_current(struct gl_context *ctx) +{ + GLuint i; + + /* Init all to (0,0,0,1) */ + for (i = 0; i < Elements(ctx->Current.Attrib); i++) { + ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 ); + } + + /* redo special cases: */ + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 ); +} + + +/** + * Init vertex/fragment/geometry program limits. + * Important: drivers should override these with actual limits. + */ +static void +init_program_limits(GLenum type, struct gl_program_constants *prog) +{ + prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS; + prog->MaxTemps = MAX_PROGRAM_TEMPS; + prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; + prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; + prog->MaxUniformComponents = 4 * MAX_UNIFORMS; + + switch (type) { + case GL_VERTEX_PROGRAM_ARB: + prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; + prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; + prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; + break; + case GL_FRAGMENT_PROGRAM_ARB: + prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; + prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; + prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; + break; + case MESA_GEOMETRY_PROGRAM: + prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS; + prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; + prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; + + prog->MaxGeometryTextureImageUnits = MAX_GEOMETRY_TEXTURE_IMAGE_UNITS; + prog->MaxGeometryVaryingComponents = MAX_GEOMETRY_VARYING_COMPONENTS; + prog->MaxVertexVaryingComponents = MAX_VERTEX_VARYING_COMPONENTS; + prog->MaxGeometryUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS; + prog->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES; + prog->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; + break; + default: + assert(0 && "Bad program type in init_program_limits()"); + } + + /* Set the native limits to zero. This implies that there is no native + * support for shaders. Let the drivers fill in the actual values. + */ + prog->MaxNativeInstructions = 0; + prog->MaxNativeAluInstructions = 0; + prog->MaxNativeTexInstructions = 0; + prog->MaxNativeTexIndirections = 0; + prog->MaxNativeAttribs = 0; + prog->MaxNativeTemps = 0; + prog->MaxNativeAddressRegs = 0; + prog->MaxNativeParameters = 0; + + /* Set GLSL datatype range/precision info assuming IEEE float values. + * Drivers should override these defaults as needed. + */ + prog->MediumFloat.RangeMin = 127; + prog->MediumFloat.RangeMax = 127; + prog->MediumFloat.Precision = 23; + prog->LowFloat = prog->HighFloat = prog->MediumFloat; + /* assume ints are stored as floats for now */ + prog->LowInt = prog->MediumInt = prog->HighInt = prog->MediumFloat; +} + + +/** + * Initialize fields of gl_constants (aka ctx->Const.*). + * Use defaults from config.h. The device drivers will often override + * some of these values (such as number of texture units). + */ +static void +_mesa_init_constants(struct gl_context *ctx) +{ + assert(ctx); + + /* Constants, may be overriden (usually only reduced) by device drivers */ + ctx->Const.MaxTextureMbytes = MAX_TEXTURE_MBYTES; + ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; + ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; + ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; + ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; + ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS; + ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS; + ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, + ctx->Const.MaxTextureImageUnits); + ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; + ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS; + ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE; + ctx->Const.SubPixelBits = SUB_PIXEL_BITS; + ctx->Const.MinPointSize = MIN_POINT_SIZE; + ctx->Const.MaxPointSize = MAX_POINT_SIZE; + ctx->Const.MinPointSizeAA = MIN_POINT_SIZE; + ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE; + ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY; + ctx->Const.MinLineWidth = MIN_LINE_WIDTH; + ctx->Const.MaxLineWidth = MAX_LINE_WIDTH; + ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH; + ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH; + ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY; + ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE; + ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES; + ctx->Const.MaxLights = MAX_LIGHTS; + ctx->Const.MaxShininess = 128.0; + ctx->Const.MaxSpotExponent = 128.0; + ctx->Const.MaxViewportWidth = MAX_WIDTH; + ctx->Const.MaxViewportHeight = MAX_HEIGHT; +#if FEATURE_ARB_vertex_program + init_program_limits(GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram); +#endif +#if FEATURE_ARB_fragment_program + init_program_limits(GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram); +#endif +#if FEATURE_ARB_geometry_shader4 + init_program_limits(MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram); +#endif + ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; + ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; + + /* CheckArrayBounds is overriden by drivers/x11 for X server */ + ctx->Const.CheckArrayBounds = GL_FALSE; + + /* GL_ARB_draw_buffers */ + ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS; + +#if FEATURE_EXT_framebuffer_object + ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS; + ctx->Const.MaxRenderbufferSize = MAX_WIDTH; +#endif + +#if FEATURE_ARB_vertex_shader + ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxVarying = MAX_VARYING; +#endif + + /* Shading language version */ + if (ctx->API == API_OPENGL) { + ctx->Const.GLSLVersion = 120; + } + else if (ctx->API == API_OPENGLES2) { + ctx->Const.GLSLVersion = 100; + } + else if (ctx->API == API_OPENGLES) { + ctx->Const.GLSLVersion = 0; /* GLSL not supported */ + } + + /* GL_ARB_framebuffer_object */ + ctx->Const.MaxSamples = 0; + + /* GL_ARB_sync */ + ctx->Const.MaxServerWaitTimeout = (GLuint64) ~0; + + /* GL_ATI_envmap_bumpmap */ + ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS; + + /* GL_EXT_provoking_vertex */ + ctx->Const.QuadsFollowProvokingVertexConvention = GL_TRUE; + + /* GL_EXT_transform_feedback */ + ctx->Const.MaxTransformFeedbackSeparateAttribs = MAX_FEEDBACK_ATTRIBS; + ctx->Const.MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS; + ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS; + + /* GL 3.2: hard-coded for now: */ + ctx->Const.ProfileMask = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; + + /** GL_EXT_gpu_shader4 */ + ctx->Const.MinProgramTexelOffset = -8; + ctx->Const.MaxProgramTexelOffset = 7; +} + + +/** + * Do some sanity checks on the limits/constants for the given context. + * Only called the first time a context is bound. + */ +static void +check_context_limits(struct gl_context *ctx) +{ + /* check that we don't exceed the size of various bitfields */ + assert(VERT_RESULT_MAX <= + (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten))); + assert(FRAG_ATTRIB_MAX <= + (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead))); + + assert(MAX_COMBINED_TEXTURE_IMAGE_UNITS <= 8 * sizeof(GLbitfield)); + + /* shader-related checks */ + assert(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); + assert(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); + + assert(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); + assert(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); + assert(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX); + assert(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX); + + /* Texture unit checks */ + assert(ctx->Const.MaxTextureImageUnits > 0); + assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); + assert(ctx->Const.MaxTextureCoordUnits > 0); + assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS); + assert(ctx->Const.MaxTextureUnits > 0); + assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS); + assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS); + assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, + ctx->Const.MaxTextureCoordUnits)); + assert(ctx->Const.MaxCombinedTextureImageUnits > 0); + assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); + assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); + /* number of coord units cannot be greater than number of image units */ + assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.MaxTextureImageUnits); + + + /* Texture size checks */ + assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS); + assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS); + assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS); + assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE); + + /* make sure largest texture image is <= MAX_WIDTH in size */ + assert((1 << (ctx->Const.MaxTextureLevels - 1)) <= MAX_WIDTH); + assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= MAX_WIDTH); + assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= MAX_WIDTH); + + /* Texture level checks */ + assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); + assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); + + /* Max texture size should be <= max viewport size (render to texture) */ + assert((1 << (MAX_TEXTURE_LEVELS - 1)) <= MAX_WIDTH); + + assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH); + assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH); + + assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS); + + /* if this fails, add more enum values to gl_buffer_index */ + assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT); + + /* XXX probably add more tests */ +} + + +/** + * Initialize the attribute groups in a GL context. + * + * \param ctx GL context. + * + * Initializes all the attributes, calling the respective <tt>init*</tt> + * functions for the more complex data structures. + */ +static GLboolean +init_attrib_groups(struct gl_context *ctx) +{ + assert(ctx); + + /* Constants */ + _mesa_init_constants( ctx ); + + /* Extensions */ + _mesa_init_extensions( ctx ); + + /* Attribute Groups */ + _mesa_init_accum( ctx ); + _mesa_init_attrib( ctx ); + _mesa_init_buffer_objects( ctx ); + _mesa_init_color( ctx ); + _mesa_init_current( ctx ); + _mesa_init_depth( ctx ); + _mesa_init_debug( ctx ); + _mesa_init_display_list( ctx ); + _mesa_init_eval( ctx ); + _mesa_init_fbobjects( ctx ); + _mesa_init_feedback( ctx ); + _mesa_init_fog( ctx ); + _mesa_init_hint( ctx ); + _mesa_init_line( ctx ); + _mesa_init_lighting( ctx ); + _mesa_init_matrix( ctx ); + _mesa_init_multisample( ctx ); + _mesa_init_pixel( ctx ); + _mesa_init_pixelstore( ctx ); + _mesa_init_point( ctx ); + _mesa_init_polygon( ctx ); + _mesa_init_program( ctx ); + _mesa_init_queryobj( ctx ); + _mesa_init_sync( ctx ); + _mesa_init_rastpos( ctx ); + _mesa_init_scissor( ctx ); + _mesa_init_shader_state( ctx ); + _mesa_init_stencil( ctx ); + _mesa_init_transform( ctx ); + _mesa_init_transform_feedback( ctx ); + _mesa_init_varray( ctx ); + _mesa_init_viewport( ctx ); + + if (!_mesa_init_texture( ctx )) + return GL_FALSE; + + _mesa_init_texture_s3tc( ctx ); + + /* Miscellaneous */ + ctx->NewState = _NEW_ALL; + ctx->ErrorValue = (GLenum) GL_NO_ERROR; + ctx->varying_vp_inputs = ~0; + + return GL_TRUE; +} + + +/** + * Update default objects in a GL context with respect to shared state. + * + * \param ctx GL context. + * + * Removes references to old default objects, (texture objects, program + * objects, etc.) and changes to reference those from the current shared + * state. + */ +static GLboolean +update_default_objects(struct gl_context *ctx) +{ + assert(ctx); + + _mesa_update_default_objects_program(ctx); + _mesa_update_default_objects_texture(ctx); + _mesa_update_default_objects_buffer_objects(ctx); + + return GL_TRUE; +} + + +/** + * This is the default function we plug into all dispatch table slots + * This helps prevents a segfault when someone calls a GL function without + * first checking if the extension's supported. + */ +static int +generic_nop(void) +{ + _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)"); + return 0; +} + + +/** + * Allocate and initialize a new dispatch table. + */ +struct _glapi_table * +_mesa_alloc_dispatch_table(int size) +{ + /* Find the larger of Mesa's dispatch table and libGL's dispatch table. + * In practice, this'll be the same for stand-alone Mesa. But for DRI + * Mesa we do this to accomodate different versions of libGL and various + * DRI drivers. + */ + GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); + struct _glapi_table *table; + + /* should never happen, but just in case */ + numEntries = MAX2(numEntries, size); + + table = (struct _glapi_table *) malloc(numEntries * sizeof(_glapi_proc)); + if (table) { + _glapi_proc *entry = (_glapi_proc *) table; + GLint i; + for (i = 0; i < numEntries; i++) { + entry[i] = (_glapi_proc) generic_nop; + } + } + return table; +} + + +/** + * Initialize a struct gl_context struct (rendering context). + * + * This includes allocating all the other structs and arrays which hang off of + * the context by pointers. + * Note that the driver needs to pass in its dd_function_table here since + * we need to at least call driverFunctions->NewTextureObject to create the + * default texture objects. + * + * Called by _mesa_create_context(). + * + * Performs the imports and exports callback tables initialization, and + * miscellaneous one-time initializations. If no shared context is supplied one + * is allocated, and increase its reference count. Setups the GL API dispatch + * tables. Initialize the TNL module. Sets the maximum Z buffer depth. + * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables + * for debug flags. + * + * \param ctx the context to initialize + * \param api the GL API type to create the context for + * \param visual describes the visual attributes for this context + * \param share_list points to context to share textures, display lists, + * etc with, or NULL + * \param driverFunctions table of device driver functions for this context + * to use + * \param driverContext pointer to driver-specific context data + */ +GLboolean +_mesa_initialize_context_for_api(struct gl_context *ctx, + gl_api api, + const struct gl_config *visual, + struct gl_context *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) +{ + struct gl_shared_state *shared; + int i; + + /*ASSERT(driverContext);*/ + assert(driverFunctions->NewTextureObject); + assert(driverFunctions->FreeTexImageData); + + ctx->API = api; + ctx->Visual = *visual; + ctx->DrawBuffer = NULL; + ctx->ReadBuffer = NULL; + ctx->WinSysDrawBuffer = NULL; + ctx->WinSysReadBuffer = NULL; + + /* misc one-time initializations */ + one_time_init(ctx); + + /* Plug in driver functions and context pointer here. + * This is important because when we call alloc_shared_state() below + * we'll call ctx->Driver.NewTextureObject() to create the default + * textures. + */ + ctx->Driver = *driverFunctions; + ctx->DriverCtx = driverContext; + + if (share_list) { + /* share state with another context */ + shared = share_list->Shared; + } + else { + /* allocate new, unshared state */ + shared = _mesa_alloc_shared_state(ctx); + if (!shared) + return GL_FALSE; + } + + _glthread_LOCK_MUTEX(shared->Mutex); + ctx->Shared = shared; + shared->RefCount++; + _glthread_UNLOCK_MUTEX(shared->Mutex); + + if (!init_attrib_groups( ctx )) { + _mesa_release_shared_state(ctx, ctx->Shared); + return GL_FALSE; + } + +#if FEATURE_dispatch + /* setup the API dispatch tables */ + switch (ctx->API) { +#if FEATURE_GL + case API_OPENGL: + ctx->Exec = _mesa_create_exec_table(); + break; +#endif +#if FEATURE_ES1 + case API_OPENGLES: + ctx->Exec = _mesa_create_exec_table_es1(); + break; +#endif +#if FEATURE_ES2 + case API_OPENGLES2: + ctx->Exec = _mesa_create_exec_table_es2(); + break; +#endif + default: + _mesa_problem(ctx, "unknown or unsupported API"); + break; + } + + if (!ctx->Exec) { + _mesa_release_shared_state(ctx, ctx->Shared); + return GL_FALSE; + } +#endif + ctx->CurrentDispatch = ctx->Exec; + + ctx->FragmentProgram._MaintainTexEnvProgram + = (_mesa_getenv("MESA_TEX_PROG") != NULL); + + ctx->VertexProgram._MaintainTnlProgram + = (_mesa_getenv("MESA_TNL_PROG") != NULL); + if (ctx->VertexProgram._MaintainTnlProgram) { + /* this is required... */ + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + } + + /* Mesa core handles all the formats that mesa core knows about. + * Drivers will want to override this list with just the formats + * they can handle, and confirm that appropriate fallbacks exist in + * _mesa_choose_tex_format(). + */ + memset(&ctx->TextureFormatSupported, GL_TRUE, + sizeof(ctx->TextureFormatSupported)); + + switch (ctx->API) { + case API_OPENGL: +#if FEATURE_dlist + ctx->Save = _mesa_create_save_table(); + if (!ctx->Save) { + _mesa_release_shared_state(ctx, ctx->Shared); + free(ctx->Exec); + return GL_FALSE; + } + + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); +#endif + break; + case API_OPENGLES: + /** + * GL_OES_texture_cube_map says + * "Initially all texture generation modes are set to REFLECTION_MAP_OES" + */ + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + texUnit->GenS.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenT.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenR.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV; + texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV; + texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; + } + break; + case API_OPENGLES2: + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; + ctx->Point.PointSprite = GL_TRUE; /* always on for ES 2.x */ + break; + } + + ctx->FirstTimeCurrent = GL_TRUE; + + return GL_TRUE; +} + + +/** + * Initialize an OpenGL context. + */ +GLboolean +_mesa_initialize_context(struct gl_context *ctx, + const struct gl_config *visual, + struct gl_context *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) +{ + return _mesa_initialize_context_for_api(ctx, + API_OPENGL, + visual, + share_list, + driverFunctions, + driverContext); +} + + +/** + * Allocate and initialize a struct gl_context structure. + * Note that the driver needs to pass in its dd_function_table here since + * we need to at least call driverFunctions->NewTextureObject to initialize + * the rendering context. + * + * \param api the GL API type to create the context for + * \param visual a struct gl_config pointer (we copy the struct contents) + * \param share_list another context to share display lists with or NULL + * \param driverFunctions points to the dd_function_table into which the + * driver has plugged in all its special functions. + * \param driverContext points to the device driver's private context state + * + * \return pointer to a new __struct gl_contextRec or NULL if error. + */ +struct gl_context * +_mesa_create_context_for_api(gl_api api, + const struct gl_config *visual, + struct gl_context *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) +{ + struct gl_context *ctx; + + ASSERT(visual); + /*ASSERT(driverContext);*/ + + ctx = (struct gl_context *) calloc(1, sizeof(struct gl_context)); + if (!ctx) + return NULL; + + if (_mesa_initialize_context_for_api(ctx, api, visual, share_list, + driverFunctions, driverContext)) { + return ctx; + } + else { + free(ctx); + return NULL; + } +} + + +/** + * Create an OpenGL context. + */ +struct gl_context * +_mesa_create_context(const struct gl_config *visual, + struct gl_context *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) +{ + return _mesa_create_context_for_api(API_OPENGL, visual, + share_list, + driverFunctions, + driverContext); +} + + +/** + * Free the data associated with the given context. + * + * But doesn't free the struct gl_context struct itself. + * + * \sa _mesa_initialize_context() and init_attrib_groups(). + */ +void +_mesa_free_context_data( struct gl_context *ctx ) +{ + if (!_mesa_get_current_context()){ + /* No current context, but we may need one in order to delete + * texture objs, etc. So temporarily bind the context now. + */ + _mesa_make_current(ctx, NULL, NULL); + } + + /* unreference WinSysDraw/Read buffers */ + _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL); + _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL); + _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL); + _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL); + + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); + + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); + + _mesa_free_attrib_data(ctx); + _mesa_free_buffer_objects(ctx); + _mesa_free_lighting_data( ctx ); + _mesa_free_eval_data( ctx ); + _mesa_free_texture_data( ctx ); + _mesa_free_matrix_data( ctx ); + _mesa_free_viewport_data( ctx ); + _mesa_free_program_data(ctx); + _mesa_free_shader_state(ctx); + _mesa_free_queryobj_data(ctx); + _mesa_free_sync_data(ctx); + _mesa_free_varray_data(ctx); + _mesa_free_transform_feedback(ctx); + + _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj); + +#if FEATURE_ARB_pixel_buffer_object + _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL); +#endif + +#if FEATURE_ARB_vertex_buffer_object + _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL); + _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj, NULL); +#endif + + /* free dispatch tables */ + free(ctx->Exec); + free(ctx->Save); + + /* Shared context state (display lists, textures, etc) */ + _mesa_release_shared_state( ctx, ctx->Shared ); + + /* needs to be after freeing shared state */ + _mesa_free_display_list_data(ctx); + + if (ctx->Extensions.String) + free((void *) ctx->Extensions.String); + + if (ctx->VersionString) + free(ctx->VersionString); + + /* unbind the context if it's currently bound */ + if (ctx == _mesa_get_current_context()) { + _mesa_make_current(NULL, NULL, NULL); + } +} + + +/** + * Destroy a struct gl_context structure. + * + * \param ctx GL context. + * + * Calls _mesa_free_context_data() and frees the gl_context object itself. + */ +void +_mesa_destroy_context( struct gl_context *ctx ) +{ + if (ctx) { + _mesa_free_context_data(ctx); + free( (void *) ctx ); + } +} + + +#if _HAVE_FULL_GL +/** + * Copy attribute groups from one context to another. + * + * \param src source context + * \param dst destination context + * \param mask bitwise OR of GL_*_BIT flags + * + * According to the bits specified in \p mask, copies the corresponding + * attributes from \p src into \p dst. For many of the attributes a simple \c + * memcpy is not enough due to the existence of internal pointers in their data + * structures. + */ +void +_mesa_copy_context( const struct gl_context *src, struct gl_context *dst, GLuint mask ) +{ + if (mask & GL_ACCUM_BUFFER_BIT) { + /* OK to memcpy */ + dst->Accum = src->Accum; + } + if (mask & GL_COLOR_BUFFER_BIT) { + /* OK to memcpy */ + dst->Color = src->Color; + } + if (mask & GL_CURRENT_BIT) { + /* OK to memcpy */ + dst->Current = src->Current; + } + if (mask & GL_DEPTH_BUFFER_BIT) { + /* OK to memcpy */ + dst->Depth = src->Depth; + } + if (mask & GL_ENABLE_BIT) { + /* no op */ + } + if (mask & GL_EVAL_BIT) { + /* OK to memcpy */ + dst->Eval = src->Eval; + } + if (mask & GL_FOG_BIT) { + /* OK to memcpy */ + dst->Fog = src->Fog; + } + if (mask & GL_HINT_BIT) { + /* OK to memcpy */ + dst->Hint = src->Hint; + } + if (mask & GL_LIGHTING_BIT) { + GLuint i; + /* begin with memcpy */ + dst->Light = src->Light; + /* fixup linked lists to prevent pointer insanity */ + make_empty_list( &(dst->Light.EnabledList) ); + for (i = 0; i < MAX_LIGHTS; i++) { + if (dst->Light.Light[i].Enabled) { + insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i])); + } + } + } + if (mask & GL_LINE_BIT) { + /* OK to memcpy */ + dst->Line = src->Line; + } + if (mask & GL_LIST_BIT) { + /* OK to memcpy */ + dst->List = src->List; + } + if (mask & GL_PIXEL_MODE_BIT) { + /* OK to memcpy */ + dst->Pixel = src->Pixel; + } + if (mask & GL_POINT_BIT) { + /* OK to memcpy */ + dst->Point = src->Point; + } + if (mask & GL_POLYGON_BIT) { + /* OK to memcpy */ + dst->Polygon = src->Polygon; + } + if (mask & GL_POLYGON_STIPPLE_BIT) { + /* Use loop instead of memcpy due to problem with Portland Group's + * C compiler. Reported by John Stone. + */ + GLuint i; + for (i = 0; i < 32; i++) { + dst->PolygonStipple[i] = src->PolygonStipple[i]; + } + } + if (mask & GL_SCISSOR_BIT) { + /* OK to memcpy */ + dst->Scissor = src->Scissor; + } + if (mask & GL_STENCIL_BUFFER_BIT) { + /* OK to memcpy */ + dst->Stencil = src->Stencil; + } + if (mask & GL_TEXTURE_BIT) { + /* Cannot memcpy because of pointers */ + _mesa_copy_texture_state(src, dst); + } + if (mask & GL_TRANSFORM_BIT) { + /* OK to memcpy */ + dst->Transform = src->Transform; + } + if (mask & GL_VIEWPORT_BIT) { + /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */ + dst->Viewport.X = src->Viewport.X; + dst->Viewport.Y = src->Viewport.Y; + dst->Viewport.Width = src->Viewport.Width; + dst->Viewport.Height = src->Viewport.Height; + dst->Viewport.Near = src->Viewport.Near; + dst->Viewport.Far = src->Viewport.Far; + _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap); + } + + /* XXX FIXME: Call callbacks? + */ + dst->NewState = _NEW_ALL; +} +#endif + + +/** + * Check if the given context can render into the given framebuffer + * by checking visual attributes. + * + * Most of these tests could go away because Mesa is now pretty flexible + * in terms of mixing rendering contexts with framebuffers. As long + * as RGB vs. CI mode agree, we're probably good. + * + * \return GL_TRUE if compatible, GL_FALSE otherwise. + */ +static GLboolean +check_compatible(const struct gl_context *ctx, + const struct gl_framebuffer *buffer) +{ + const struct gl_config *ctxvis = &ctx->Visual; + const struct gl_config *bufvis = &buffer->Visual; + + if (buffer == _mesa_get_incomplete_framebuffer()) + return GL_TRUE; + +#if 0 + /* disabling this fixes the fgl_glxgears pbuffer demo */ + if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode) + return GL_FALSE; +#endif + if (ctxvis->stereoMode && !bufvis->stereoMode) + return GL_FALSE; + if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer) + return GL_FALSE; + if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer) + return GL_FALSE; + if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer) + return GL_FALSE; + if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask) + return GL_FALSE; + if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask) + return GL_FALSE; + if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask) + return GL_FALSE; +#if 0 + /* disabled (see bug 11161) */ + if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits) + return GL_FALSE; +#endif + if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits) + return GL_FALSE; + + return GL_TRUE; +} + + +/** + * Do one-time initialization for the given framebuffer. Specifically, + * ask the driver for the window's current size and update the framebuffer + * object to match. + * Really, the device driver should totally take care of this. + */ +static void +initialize_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + GLuint width, height; + if (ctx->Driver.GetBufferSize) { + ctx->Driver.GetBufferSize(fb, &width, &height); + if (ctx->Driver.ResizeBuffers) + ctx->Driver.ResizeBuffers(ctx, fb, width, height); + fb->Initialized = GL_TRUE; + } +} + + +/** + * Check if the viewport/scissor size has not yet been initialized. + * Initialize the size if the given width and height are non-zero. + */ +void +_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) +{ + if (!ctx->ViewportInitialized && width > 0 && height > 0) { + /* Note: set flag here, before calling _mesa_set_viewport(), to prevent + * potential infinite recursion. + */ + ctx->ViewportInitialized = GL_TRUE; + _mesa_set_viewport(ctx, 0, 0, width, height); + _mesa_set_scissor(ctx, 0, 0, width, height); + } +} + + +/** + * Bind the given context to the given drawBuffer and readBuffer and + * make it the current context for the calling thread. + * We'll render into the drawBuffer and read pixels from the + * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc). + * + * We check that the context's and framebuffer's visuals are compatible + * and return immediately if they're not. + * + * \param newCtx the new GL context. If NULL then there will be no current GL + * context. + * \param drawBuffer the drawing framebuffer + * \param readBuffer the reading framebuffer + */ +GLboolean +_mesa_make_current( struct gl_context *newCtx, + struct gl_framebuffer *drawBuffer, + struct gl_framebuffer *readBuffer ) +{ + GET_CURRENT_CONTEXT(curCtx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(newCtx, "_mesa_make_current()\n"); + + /* Check that the context's and framebuffer's visuals are compatible. + */ + if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) { + if (!check_compatible(newCtx, drawBuffer)) { + _mesa_warning(newCtx, + "MakeCurrent: incompatible visuals for context and drawbuffer"); + return GL_FALSE; + } + } + if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) { + if (!check_compatible(newCtx, readBuffer)) { + _mesa_warning(newCtx, + "MakeCurrent: incompatible visuals for context and readbuffer"); + return GL_FALSE; + } + } + + if (curCtx && + (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */ + curCtx != newCtx) + _mesa_flush(curCtx); + + /* We used to call _glapi_check_multithread() here. Now do it in drivers */ + _glapi_set_context((void *) newCtx); + ASSERT(_mesa_get_current_context() == newCtx); + + if (!newCtx) { + _glapi_set_dispatch(NULL); /* none current */ + } + else { + _glapi_set_dispatch(newCtx->CurrentDispatch); + + if (drawBuffer && readBuffer) { + /* TODO: check if newCtx and buffer's visual match??? */ + + ASSERT(drawBuffer->Name == 0); + ASSERT(readBuffer->Name == 0); + _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer); + _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer); + + /* + * Only set the context's Draw/ReadBuffer fields if they're NULL + * or not bound to a user-created FBO. + */ + if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { + /* KW: merge conflict here, revisit. + */ + /* fix up the fb fields - these will end up wrong otherwise + * if the DRIdrawable changes, and everything relies on them. + * This is a bit messy (same as needed in _mesa_BindFramebufferEXT) + */ + unsigned int i; + GLenum buffers[MAX_DRAW_BUFFERS]; + + _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); + + for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) { + buffers[i] = newCtx->Color.DrawBuffer[i]; + } + + _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers, + buffers, NULL); + } + if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { + _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); + } + + /* XXX only set this flag if we're really changing the draw/read + * framebuffer bindings. + */ + newCtx->NewState |= _NEW_BUFFERS; + +#if 1 + /* We want to get rid of these lines: */ + +#if _HAVE_FULL_GL + if (!drawBuffer->Initialized) { + initialize_framebuffer_size(newCtx, drawBuffer); + } + if (readBuffer != drawBuffer && !readBuffer->Initialized) { + initialize_framebuffer_size(newCtx, readBuffer); + } + + _mesa_resizebuffers(newCtx); +#endif + +#else + /* We want the drawBuffer and readBuffer to be initialized by + * the driver. + * This generally means the Width and Height match the actual + * window size and the renderbuffers (both hardware and software + * based) are allocated to match. The later can generally be + * done with a call to _mesa_resize_framebuffer(). + * + * It's theoretically possible for a buffer to have zero width + * or height, but for now, assert check that the driver did what's + * expected of it. + */ + ASSERT(drawBuffer->Width > 0); + ASSERT(drawBuffer->Height > 0); +#endif + + if (drawBuffer) { + _mesa_check_init_viewport(newCtx, + drawBuffer->Width, drawBuffer->Height); + } + } + + if (newCtx->FirstTimeCurrent) { + _mesa_compute_version(newCtx); + + newCtx->Extensions.String = _mesa_make_extension_string(newCtx); + + check_context_limits(newCtx); + + /* We can use this to help debug user's problems. Tell them to set + * the MESA_INFO env variable before running their app. Then the + * first time each context is made current we'll print some useful + * information. + */ + if (_mesa_getenv("MESA_INFO")) { + _mesa_print_info(); + } + + newCtx->FirstTimeCurrent = GL_FALSE; + } + } + + return GL_TRUE; +} + + +/** + * Make context 'ctx' share the display lists, textures and programs + * that are associated with 'ctxToShare'. + * Any display lists, textures or programs associated with 'ctx' will + * be deleted if nobody else is sharing them. + */ +GLboolean +_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare) +{ + if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { + struct gl_shared_state *oldSharedState = ctx->Shared; + + ctx->Shared = ctxToShare->Shared; + + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); + ctx->Shared->RefCount++; + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + + update_default_objects(ctx); + + _mesa_release_shared_state(ctx, oldSharedState); + + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + + +/** + * \return pointer to the current GL context for this thread. + * + * Calls _glapi_get_context(). This isn't the fastest way to get the current + * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in + * context.h. + */ +struct gl_context * +_mesa_get_current_context( void ) +{ + return (struct gl_context *) _glapi_get_context(); +} + + +/** + * Get context's current API dispatch table. + * + * It'll either be the immediate-mode execute dispatcher or the display list + * compile dispatcher. + * + * \param ctx GL context. + * + * \return pointer to dispatch_table. + * + * Simply returns __struct gl_contextRec::CurrentDispatch. + */ +struct _glapi_table * +_mesa_get_dispatch(struct gl_context *ctx) +{ + return ctx->CurrentDispatch; +} + +/*@}*/ + + +/**********************************************************************/ +/** \name Miscellaneous functions */ +/**********************************************************************/ +/*@{*/ + +/** + * Record an error. + * + * \param ctx GL context. + * \param error error code. + * + * Records the given error code and call the driver's dd_function_table::Error + * function if defined. + * + * \sa + * This is called via _mesa_error(). + */ +void +_mesa_record_error(struct gl_context *ctx, GLenum error) +{ + if (!ctx) + return; + + if (ctx->ErrorValue == GL_NO_ERROR) { + ctx->ErrorValue = error; + } + + /* Call device driver's error handler, if any. This is used on the Mac. */ + if (ctx->Driver.Error) { + ctx->Driver.Error(ctx); + } +} + + +/** + * Flush commands and wait for completion. + */ +void +_mesa_finish(struct gl_context *ctx) +{ + FLUSH_CURRENT( ctx, 0 ); + if (ctx->Driver.Finish) { + ctx->Driver.Finish(ctx); + } +} + + +/** + * Flush commands. + */ +void +_mesa_flush(struct gl_context *ctx) +{ + FLUSH_CURRENT( ctx, 0 ); + if (ctx->Driver.Flush) { + ctx->Driver.Flush(ctx); + } +} + + + +/** + * Execute glFinish(). + * + * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the + * dd_function_table::Finish driver callback, if not NULL. + */ +void GLAPIENTRY +_mesa_Finish(void) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + _mesa_finish(ctx); +} + + +/** + * Execute glFlush(). + * + * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the + * dd_function_table::Flush driver callback, if not NULL. + */ +void GLAPIENTRY +_mesa_Flush(void) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + _mesa_flush(ctx); +} + + +/** + * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over + * MUL/MAD, or vice versa, call this function to register that. + * Otherwise we default to MUL/MAD. + */ +void +_mesa_set_mvp_with_dp4( struct gl_context *ctx, + GLboolean flag ) +{ + ctx->mvp_with_dp4 = flag; +} + + + +/** + * Prior to drawing anything with glBegin, glDrawArrays, etc. this function + * is called to see if it's valid to render. This involves checking that + * the current shader is valid and the framebuffer is complete. + * If an error is detected it'll be recorded here. + * \return GL_TRUE if OK to render, GL_FALSE if not + */ +GLboolean +_mesa_valid_to_render(struct gl_context *ctx, const char *where) +{ + bool vert_from_glsl_shader = false; + bool geom_from_glsl_shader = false; + bool frag_from_glsl_shader = false; + + /* This depends on having up to date derived state (shaders) */ + if (ctx->NewState) + _mesa_update_state(ctx); + + if (ctx->Shader.CurrentVertexProgram) { + vert_from_glsl_shader = true; + + if (!ctx->Shader.CurrentVertexProgram->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(shader not linked)", where); + return GL_FALSE; + } +#if 0 /* not normally enabled */ + { + char errMsg[100]; + if (!_mesa_validate_shader_program(ctx, + ctx->Shader.CurrentVertexProgram, + errMsg)) { + _mesa_warning(ctx, "Shader program %u is invalid: %s", + ctx->Shader.CurrentVertexProgram->Name, errMsg); + } + } +#endif + } + + if (ctx->Shader.CurrentGeometryProgram) { + geom_from_glsl_shader = true; + + if (!ctx->Shader.CurrentGeometryProgram->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(shader not linked)", where); + return GL_FALSE; + } +#if 0 /* not normally enabled */ + { + char errMsg[100]; + if (!_mesa_validate_shader_program(ctx, + ctx->Shader.CurrentGeometryProgram, + errMsg)) { + _mesa_warning(ctx, "Shader program %u is invalid: %s", + ctx->Shader.CurrentGeometryProgram->Name, errMsg); + } + } +#endif + } + + if (ctx->Shader.CurrentFragmentProgram) { + frag_from_glsl_shader = true; + + if (!ctx->Shader.CurrentFragmentProgram->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(shader not linked)", where); + return GL_FALSE; + } +#if 0 /* not normally enabled */ + { + char errMsg[100]; + if (!_mesa_validate_shader_program(ctx, + ctx->Shader.CurrentFragmentProgram, + errMsg)) { + _mesa_warning(ctx, "Shader program %u is invalid: %s", + ctx->Shader.CurrentFragmentProgram->Name, errMsg); + } + } +#endif + } + + /* Any shader stages that are not supplied by the GLSL shader and have + * assembly shaders enabled must now be validated. + */ + if (!vert_from_glsl_shader + && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(vertex program not valid)", where); + return GL_FALSE; + } + + /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current + * FINISHME: geometry program should validated here. + */ + (void) geom_from_glsl_shader; + + if (!frag_from_glsl_shader) { + if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(fragment program not valid)", where); + return GL_FALSE; + } + + /* If drawing to integer-valued color buffers, there must be an + * active fragment shader (GL_EXT_texture_integer). + */ + if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(integer format but no fragment shader)", where); + return GL_FALSE; + } + } + + if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, + "%s(incomplete framebuffer)", where); + return GL_FALSE; + } + +#ifdef DEBUG + if (ctx->Shader.Flags & GLSL_LOG) { + struct gl_shader_program *shProg[MESA_SHADER_TYPES]; + gl_shader_type i; + + shProg[MESA_SHADER_VERTEX] = ctx->Shader.CurrentVertexProgram; + shProg[MESA_SHADER_GEOMETRY] = ctx->Shader.CurrentGeometryProgram; + shProg[MESA_SHADER_FRAGMENT] = ctx->Shader.CurrentFragmentProgram; + + for (i = 0; i < MESA_SHADER_TYPES; i++) { + struct gl_shader *sh; + + if (shProg[i] == NULL || shProg[i]->_Used + || shProg[i]->_LinkedShaders[i] == NULL) + continue; + + /* This is the first time this shader is being used. + * Append shader's constants/uniforms to log file. + * + * The logic is a little odd here. We only want to log data for each + * shader target that will actually be used, and we only want to log + * it once. It's possible to have a program bound to the vertex + * shader target that also supplied a fragment shader. If that + * program isn't also bound to the fragment shader target we don't + * want to log its fragment data. + */ + sh = shProg[i]->_LinkedShaders[i]; + switch (sh->Type) { + case GL_VERTEX_SHADER: + _mesa_append_uniforms_to_file(sh, &shProg[i]->VertexProgram->Base); + break; + + case GL_GEOMETRY_SHADER_ARB: + _mesa_append_uniforms_to_file(sh, + &shProg[i]->GeometryProgram->Base); + break; + + case GL_FRAGMENT_SHADER: + _mesa_append_uniforms_to_file(sh, + &shProg[i]->FragmentProgram->Base); + break; + } + } + + for (i = 0; i < MESA_SHADER_TYPES; i++) { + if (shProg[i] != NULL) + shProg[i]->_Used = GL_TRUE; + } + } +#endif + + return GL_TRUE; +} + + +/*@}*/ diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 02eeca2a4..ac2957ac8 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1,3344 +1,3358 @@ -/*
- * Mesa 3-D graphics library
- * Version: 7.7
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file mtypes.h
- * Main Mesa data structures.
- *
- * Please try to mark derived values with a leading underscore ('_').
- */
-
-#ifndef MTYPES_H
-#define MTYPES_H
-
-
-#include "main/glheader.h"
-#include "main/config.h"
-#include "main/mfeatures.h"
-#include "glapi/glapi.h"
-#include "math/m_matrix.h" /* GLmatrix */
-#include "main/simple_list.h" /* struct simple_node */
-#include "main/formats.h" /* MESA_FORMAT_COUNT */
-
-
-/**
- * Color channel data type.
- */
-#if CHAN_BITS == 8
- typedef GLubyte GLchan;
-#define CHAN_MAX 255
-#define CHAN_MAXF 255.0F
-#define CHAN_TYPE GL_UNSIGNED_BYTE
-#elif CHAN_BITS == 16
- typedef GLushort GLchan;
-#define CHAN_MAX 65535
-#define CHAN_MAXF 65535.0F
-#define CHAN_TYPE GL_UNSIGNED_SHORT
-#elif CHAN_BITS == 32
- typedef GLfloat GLchan;
-#define CHAN_MAX 1.0
-#define CHAN_MAXF 1.0F
-#define CHAN_TYPE GL_FLOAT
-#else
-#error "illegal number of color channel bits"
-#endif
-
-
-/**
- * Stencil buffer data type.
- */
-#if STENCIL_BITS==8
- typedef GLubyte GLstencil;
-#elif STENCIL_BITS==16
- typedef GLushort GLstencil;
-#else
-# error "illegal number of stencil bits"
-#endif
-
-
-/**
- * \name 64-bit extension of GLbitfield.
- */
-/*@{*/
-typedef GLuint64 GLbitfield64;
-
-#define BITFIELD64_ONE 1ULL
-#define BITFIELD64_ALLONES ~0ULL
-
-/** Set a single bit */
-#define BITFIELD64_BIT(b) (BITFIELD64_ONE << (b))
-
-/** Set a mask of the least significant \c b bits */
-#define BITFIELD64_MASK(b) (((b) >= 64) ? BITFIELD64_ALLONES : \
- (BITFIELD64_BIT(b) - 1))
-
-/**
- * Set all bits from l (low bit) to h (high bit), inclusive.
- *
- * \note \C BITFIELD_64_RANGE(0, 63) return 64 set bits.
- */
-#define BITFIELD64_RANGE(l, h) (BITFIELD64_MASK((h) + 1) & ~BITFIELD64_MASK(l))
-/*@}*/
-
-
-/**
- * \name Some forward type declarations
- */
-/*@{*/
-struct _mesa_HashTable;
-struct gl_attrib_node;
-struct gl_list_extensions;
-struct gl_meta_state;
-struct gl_pixelstore_attrib;
-struct gl_program_cache;
-struct gl_texture_format;
-struct gl_texture_image;
-struct gl_texture_object;
-struct gl_context;
-struct st_context;
-/*@}*/
-
-
-
-/**
- * Shader stages. Note that these will become 5 with tessellation.
- * These MUST have the same values as gallium's PIPE_SHADER_*
- */
-typedef enum
-{
- MESA_SHADER_VERTEX = 0,
- MESA_SHADER_FRAGMENT = 1,
- MESA_SHADER_GEOMETRY = 2,
- MESA_SHADER_TYPES = 3
-} gl_shader_type;
-
-
-
-/**
- * Indexes for vertex program attributes.
- * GL_NV_vertex_program aliases generic attributes over the conventional
- * attributes. In GL_ARB_vertex_program shader the aliasing is optional.
- * In GL_ARB_vertex_shader / OpenGL 2.0 the aliasing is disallowed (the
- * generic attributes are distinct/separate).
- */
-typedef enum
-{
- VERT_ATTRIB_POS = 0,
- VERT_ATTRIB_WEIGHT = 1,
- VERT_ATTRIB_NORMAL = 2,
- VERT_ATTRIB_COLOR0 = 3,
- VERT_ATTRIB_COLOR1 = 4,
- VERT_ATTRIB_FOG = 5,
- VERT_ATTRIB_COLOR_INDEX = 6,
- VERT_ATTRIB_POINT_SIZE = 6, /*alias*/
- VERT_ATTRIB_EDGEFLAG = 7,
- VERT_ATTRIB_TEX0 = 8,
- VERT_ATTRIB_TEX1 = 9,
- VERT_ATTRIB_TEX2 = 10,
- VERT_ATTRIB_TEX3 = 11,
- VERT_ATTRIB_TEX4 = 12,
- VERT_ATTRIB_TEX5 = 13,
- VERT_ATTRIB_TEX6 = 14,
- VERT_ATTRIB_TEX7 = 15,
- VERT_ATTRIB_GENERIC0 = 16,
- VERT_ATTRIB_GENERIC1 = 17,
- VERT_ATTRIB_GENERIC2 = 18,
- VERT_ATTRIB_GENERIC3 = 19,
- VERT_ATTRIB_GENERIC4 = 20,
- VERT_ATTRIB_GENERIC5 = 21,
- VERT_ATTRIB_GENERIC6 = 22,
- VERT_ATTRIB_GENERIC7 = 23,
- VERT_ATTRIB_GENERIC8 = 24,
- VERT_ATTRIB_GENERIC9 = 25,
- VERT_ATTRIB_GENERIC10 = 26,
- VERT_ATTRIB_GENERIC11 = 27,
- VERT_ATTRIB_GENERIC12 = 28,
- VERT_ATTRIB_GENERIC13 = 29,
- VERT_ATTRIB_GENERIC14 = 30,
- VERT_ATTRIB_GENERIC15 = 31,
- VERT_ATTRIB_MAX = 32
-} gl_vert_attrib;
-
-/**
- * Bitflags for vertex attributes.
- * These are used in bitfields in many places.
- */
-/*@{*/
-#define VERT_BIT_POS (1 << VERT_ATTRIB_POS)
-#define VERT_BIT_WEIGHT (1 << VERT_ATTRIB_WEIGHT)
-#define VERT_BIT_NORMAL (1 << VERT_ATTRIB_NORMAL)
-#define VERT_BIT_COLOR0 (1 << VERT_ATTRIB_COLOR0)
-#define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1)
-#define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG)
-#define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX)
-#define VERT_BIT_EDGEFLAG (1 << VERT_ATTRIB_EDGEFLAG)
-#define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0)
-#define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1)
-#define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2)
-#define VERT_BIT_TEX3 (1 << VERT_ATTRIB_TEX3)
-#define VERT_BIT_TEX4 (1 << VERT_ATTRIB_TEX4)
-#define VERT_BIT_TEX5 (1 << VERT_ATTRIB_TEX5)
-#define VERT_BIT_TEX6 (1 << VERT_ATTRIB_TEX6)
-#define VERT_BIT_TEX7 (1 << VERT_ATTRIB_TEX7)
-#define VERT_BIT_GENERIC0 (1 << VERT_ATTRIB_GENERIC0)
-#define VERT_BIT_GENERIC1 (1 << VERT_ATTRIB_GENERIC1)
-#define VERT_BIT_GENERIC2 (1 << VERT_ATTRIB_GENERIC2)
-#define VERT_BIT_GENERIC3 (1 << VERT_ATTRIB_GENERIC3)
-#define VERT_BIT_GENERIC4 (1 << VERT_ATTRIB_GENERIC4)
-#define VERT_BIT_GENERIC5 (1 << VERT_ATTRIB_GENERIC5)
-#define VERT_BIT_GENERIC6 (1 << VERT_ATTRIB_GENERIC6)
-#define VERT_BIT_GENERIC7 (1 << VERT_ATTRIB_GENERIC7)
-#define VERT_BIT_GENERIC8 (1 << VERT_ATTRIB_GENERIC8)
-#define VERT_BIT_GENERIC9 (1 << VERT_ATTRIB_GENERIC9)
-#define VERT_BIT_GENERIC10 (1 << VERT_ATTRIB_GENERIC10)
-#define VERT_BIT_GENERIC11 (1 << VERT_ATTRIB_GENERIC11)
-#define VERT_BIT_GENERIC12 (1 << VERT_ATTRIB_GENERIC12)
-#define VERT_BIT_GENERIC13 (1 << VERT_ATTRIB_GENERIC13)
-#define VERT_BIT_GENERIC14 (1 << VERT_ATTRIB_GENERIC14)
-#define VERT_BIT_GENERIC15 (1 << VERT_ATTRIB_GENERIC15)
-
-#define VERT_BIT_TEX(u) (1 << (VERT_ATTRIB_TEX0 + (u)))
-#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g)))
-/*@}*/
-
-
-/**
- * Indexes for vertex program result attributes
- */
-typedef enum
-{
- VERT_RESULT_HPOS = 0,
- VERT_RESULT_COL0 = 1,
- VERT_RESULT_COL1 = 2,
- VERT_RESULT_FOGC = 3,
- VERT_RESULT_TEX0 = 4,
- VERT_RESULT_TEX1 = 5,
- VERT_RESULT_TEX2 = 6,
- VERT_RESULT_TEX3 = 7,
- VERT_RESULT_TEX4 = 8,
- VERT_RESULT_TEX5 = 9,
- VERT_RESULT_TEX6 = 10,
- VERT_RESULT_TEX7 = 11,
- VERT_RESULT_PSIZ = 12,
- VERT_RESULT_BFC0 = 13,
- VERT_RESULT_BFC1 = 14,
- VERT_RESULT_EDGE = 15,
- VERT_RESULT_VAR0 = 16, /**< shader varying */
- VERT_RESULT_MAX = (VERT_RESULT_VAR0 + MAX_VARYING)
-} gl_vert_result;
-
-
-/*********************************************/
-
-/**
- * Indexes for geometry program attributes.
- */
-typedef enum
-{
- GEOM_ATTRIB_POSITION = 0,
- GEOM_ATTRIB_COLOR0 = 1,
- GEOM_ATTRIB_COLOR1 = 2,
- GEOM_ATTRIB_SECONDARY_COLOR0 = 3,
- GEOM_ATTRIB_SECONDARY_COLOR1 = 4,
- GEOM_ATTRIB_FOG_FRAG_COORD = 5,
- GEOM_ATTRIB_POINT_SIZE = 6,
- GEOM_ATTRIB_CLIP_VERTEX = 7,
- GEOM_ATTRIB_PRIMITIVE_ID = 8,
- GEOM_ATTRIB_TEX_COORD = 9,
-
- GEOM_ATTRIB_VAR0 = 16,
- GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING)
-} gl_geom_attrib;
-
-/**
- * Bitflags for geometry attributes.
- * These are used in bitfields in many places.
- */
-/*@{*/
-#define GEOM_BIT_COLOR0 (1 << GEOM_ATTRIB_COLOR0)
-#define GEOM_BIT_COLOR1 (1 << GEOM_ATTRIB_COLOR1)
-#define GEOM_BIT_SCOLOR0 (1 << GEOM_ATTRIB_SECONDARY_COLOR0)
-#define GEOM_BIT_SCOLOR1 (1 << GEOM_ATTRIB_SECONDARY_COLOR1)
-#define GEOM_BIT_TEX_COORD (1 << GEOM_ATTRIB_TEX_COORD)
-#define GEOM_BIT_FOG_COORD (1 << GEOM_ATTRIB_FOG_FRAG_COORD)
-#define GEOM_BIT_POSITION (1 << GEOM_ATTRIB_POSITION)
-#define GEOM_BIT_POINT_SIDE (1 << GEOM_ATTRIB_POINT_SIZE)
-#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX)
-#define GEOM_BIT_PRIM_ID (1 << GEOM_ATTRIB_PRIMITIVE_ID)
-#define GEOM_BIT_VAR0 (1 << GEOM_ATTRIB_VAR0)
-
-#define GEOM_BIT_VAR(g) (1 << (GEOM_BIT_VAR0 + (g)))
-/*@}*/
-
-
-/**
- * Indexes for geometry program result attributes
- */
-/*@{*/
-typedef enum {
- GEOM_RESULT_POS = 0,
- GEOM_RESULT_COL0 = 1,
- GEOM_RESULT_COL1 = 2,
- GEOM_RESULT_SCOL0 = 3,
- GEOM_RESULT_SCOL1 = 4,
- GEOM_RESULT_FOGC = 5,
- GEOM_RESULT_TEX0 = 6,
- GEOM_RESULT_TEX1 = 7,
- GEOM_RESULT_TEX2 = 8,
- GEOM_RESULT_TEX3 = 9,
- GEOM_RESULT_TEX4 = 10,
- GEOM_RESULT_TEX5 = 11,
- GEOM_RESULT_TEX6 = 12,
- GEOM_RESULT_TEX7 = 13,
- GEOM_RESULT_PSIZ = 14,
- GEOM_RESULT_CLPV = 15,
- GEOM_RESULT_PRID = 16,
- GEOM_RESULT_LAYR = 17,
- GEOM_RESULT_VAR0 = 18, /**< shader varying, should really be 16 */
- /* ### we need to -2 because var0 is 18 instead 16 like in the others */
- GEOM_RESULT_MAX = (GEOM_RESULT_VAR0 + MAX_VARYING - 2)
-} gl_geom_result;
-/*@}*/
-
-/**
- * Indexes for fragment program input attributes.
- */
-typedef enum
-{
- FRAG_ATTRIB_WPOS = 0,
- FRAG_ATTRIB_COL0 = 1,
- FRAG_ATTRIB_COL1 = 2,
- FRAG_ATTRIB_FOGC = 3,
- FRAG_ATTRIB_TEX0 = 4,
- FRAG_ATTRIB_TEX1 = 5,
- FRAG_ATTRIB_TEX2 = 6,
- FRAG_ATTRIB_TEX3 = 7,
- FRAG_ATTRIB_TEX4 = 8,
- FRAG_ATTRIB_TEX5 = 9,
- FRAG_ATTRIB_TEX6 = 10,
- FRAG_ATTRIB_TEX7 = 11,
- FRAG_ATTRIB_FACE = 12, /**< front/back face */
- FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */
- FRAG_ATTRIB_VAR0 = 14, /**< shader varying */
- FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
-} gl_frag_attrib;
-
-/**
- * Bitflags for fragment program input attributes.
- */
-/*@{*/
-#define FRAG_BIT_WPOS (1 << FRAG_ATTRIB_WPOS)
-#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
-#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
-#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
-#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE)
-#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC)
-#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
-#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
-#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
-#define FRAG_BIT_TEX3 (1 << FRAG_ATTRIB_TEX3)
-#define FRAG_BIT_TEX4 (1 << FRAG_ATTRIB_TEX4)
-#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5)
-#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6)
-#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7)
-#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0)
-
-#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U))
-#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V))
-
-#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \
- FRAG_BIT_TEX1| \
- FRAG_BIT_TEX2| \
- FRAG_BIT_TEX3| \
- FRAG_BIT_TEX4| \
- FRAG_BIT_TEX5| \
- FRAG_BIT_TEX6| \
- FRAG_BIT_TEX7)
-/*@}*/
-
-
-/**
- * Fragment program results
- */
-typedef enum
-{
- FRAG_RESULT_DEPTH = 0,
- FRAG_RESULT_STENCIL = 1,
- FRAG_RESULT_COLOR = 2,
- FRAG_RESULT_DATA0 = 3,
- FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
-} gl_frag_result;
-
-
-/**
- * Indexes for all renderbuffers
- */
-typedef enum
-{
- /* the four standard color buffers */
- BUFFER_FRONT_LEFT,
- BUFFER_BACK_LEFT,
- BUFFER_FRONT_RIGHT,
- BUFFER_BACK_RIGHT,
- BUFFER_DEPTH,
- BUFFER_STENCIL,
- BUFFER_ACCUM,
- /* optional aux buffer */
- BUFFER_AUX0,
- /* generic renderbuffers */
- BUFFER_COLOR0,
- BUFFER_COLOR1,
- BUFFER_COLOR2,
- BUFFER_COLOR3,
- BUFFER_COLOR4,
- BUFFER_COLOR5,
- BUFFER_COLOR6,
- BUFFER_COLOR7,
- BUFFER_COUNT
-} gl_buffer_index;
-
-/**
- * Bit flags for all renderbuffers
- */
-#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT)
-#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT)
-#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT)
-#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT)
-#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0)
-#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1)
-#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2)
-#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3)
-#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH)
-#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL)
-#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM)
-#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0)
-#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1)
-#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2)
-#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3)
-#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4)
-#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5)
-#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6)
-#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7)
-
-/**
- * Mask of all the color buffer bits (but not accum).
- */
-#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \
- BUFFER_BIT_BACK_LEFT | \
- BUFFER_BIT_FRONT_RIGHT | \
- BUFFER_BIT_BACK_RIGHT | \
- BUFFER_BIT_AUX0 | \
- BUFFER_BIT_COLOR0 | \
- BUFFER_BIT_COLOR1 | \
- BUFFER_BIT_COLOR2 | \
- BUFFER_BIT_COLOR3 | \
- BUFFER_BIT_COLOR4 | \
- BUFFER_BIT_COLOR5 | \
- BUFFER_BIT_COLOR6 | \
- BUFFER_BIT_COLOR7)
-
-
-/**
- * Framebuffer configuration (aka visual / pixelformat)
- * Note: some of these fields should be boolean, but it appears that
- * code in drivers/dri/common/util.c requires int-sized fields.
- */
-struct gl_config
-{
- GLboolean rgbMode;
- GLboolean floatMode;
- GLboolean colorIndexMode; /* XXX is this used anywhere? */
- GLuint doubleBufferMode;
- GLuint stereoMode;
-
- GLboolean haveAccumBuffer;
- GLboolean haveDepthBuffer;
- GLboolean haveStencilBuffer;
-
- GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
- GLuint redMask, greenMask, blueMask, alphaMask;
- GLint rgbBits; /* total bits for rgb */
- GLint indexBits; /* total bits for colorindex */
-
- GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
- GLint depthBits;
- GLint stencilBits;
-
- GLint numAuxBuffers;
-
- GLint level;
-
- /* EXT_visual_rating / GLX 1.2 */
- GLint visualRating;
-
- /* EXT_visual_info / GLX 1.2 */
- GLint transparentPixel;
- /* colors are floats scaled to ints */
- GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
- GLint transparentIndex;
-
- /* ARB_multisample / SGIS_multisample */
- GLint sampleBuffers;
- GLint samples;
-
- /* SGIX_pbuffer / GLX 1.3 */
- GLint maxPbufferWidth;
- GLint maxPbufferHeight;
- GLint maxPbufferPixels;
- GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
- GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
-
- /* OML_swap_method */
- GLint swapMethod;
-
- /* EXT_texture_from_pixmap */
- GLint bindToTextureRgb;
- GLint bindToTextureRgba;
- GLint bindToMipmapTexture;
- GLint bindToTextureTargets;
- GLint yInverted;
-};
-
-
-/**
- * Data structure for color tables
- */
-struct gl_color_table
-{
- GLenum InternalFormat; /**< The user-specified format */
- GLenum _BaseFormat; /**< GL_ALPHA, GL_RGBA, GL_RGB, etc */
- GLuint Size; /**< number of entries in table */
- GLfloat *TableF; /**< Color table, floating point values */
- GLubyte *TableUB; /**< Color table, ubyte values */
- GLubyte RedSize;
- GLubyte GreenSize;
- GLubyte BlueSize;
- GLubyte AlphaSize;
- GLubyte LuminanceSize;
- GLubyte IntensitySize;
-};
-
-
-/**
- * \name Bit flags used for updating material values.
- */
-/*@{*/
-#define MAT_ATTRIB_FRONT_AMBIENT 0
-#define MAT_ATTRIB_BACK_AMBIENT 1
-#define MAT_ATTRIB_FRONT_DIFFUSE 2
-#define MAT_ATTRIB_BACK_DIFFUSE 3
-#define MAT_ATTRIB_FRONT_SPECULAR 4
-#define MAT_ATTRIB_BACK_SPECULAR 5
-#define MAT_ATTRIB_FRONT_EMISSION 6
-#define MAT_ATTRIB_BACK_EMISSION 7
-#define MAT_ATTRIB_FRONT_SHININESS 8
-#define MAT_ATTRIB_BACK_SHININESS 9
-#define MAT_ATTRIB_FRONT_INDEXES 10
-#define MAT_ATTRIB_BACK_INDEXES 11
-#define MAT_ATTRIB_MAX 12
-
-#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f))
-#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f))
-#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f))
-#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f))
-#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f))
-#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f))
-
-#define MAT_INDEX_AMBIENT 0
-#define MAT_INDEX_DIFFUSE 1
-#define MAT_INDEX_SPECULAR 2
-
-#define MAT_BIT_FRONT_AMBIENT (1<<MAT_ATTRIB_FRONT_AMBIENT)
-#define MAT_BIT_BACK_AMBIENT (1<<MAT_ATTRIB_BACK_AMBIENT)
-#define MAT_BIT_FRONT_DIFFUSE (1<<MAT_ATTRIB_FRONT_DIFFUSE)
-#define MAT_BIT_BACK_DIFFUSE (1<<MAT_ATTRIB_BACK_DIFFUSE)
-#define MAT_BIT_FRONT_SPECULAR (1<<MAT_ATTRIB_FRONT_SPECULAR)
-#define MAT_BIT_BACK_SPECULAR (1<<MAT_ATTRIB_BACK_SPECULAR)
-#define MAT_BIT_FRONT_EMISSION (1<<MAT_ATTRIB_FRONT_EMISSION)
-#define MAT_BIT_BACK_EMISSION (1<<MAT_ATTRIB_BACK_EMISSION)
-#define MAT_BIT_FRONT_SHININESS (1<<MAT_ATTRIB_FRONT_SHININESS)
-#define MAT_BIT_BACK_SHININESS (1<<MAT_ATTRIB_BACK_SHININESS)
-#define MAT_BIT_FRONT_INDEXES (1<<MAT_ATTRIB_FRONT_INDEXES)
-#define MAT_BIT_BACK_INDEXES (1<<MAT_ATTRIB_BACK_INDEXES)
-
-
-#define FRONT_MATERIAL_BITS (MAT_BIT_FRONT_EMISSION | \
- MAT_BIT_FRONT_AMBIENT | \
- MAT_BIT_FRONT_DIFFUSE | \
- MAT_BIT_FRONT_SPECULAR | \
- MAT_BIT_FRONT_SHININESS | \
- MAT_BIT_FRONT_INDEXES)
-
-#define BACK_MATERIAL_BITS (MAT_BIT_BACK_EMISSION | \
- MAT_BIT_BACK_AMBIENT | \
- MAT_BIT_BACK_DIFFUSE | \
- MAT_BIT_BACK_SPECULAR | \
- MAT_BIT_BACK_SHININESS | \
- MAT_BIT_BACK_INDEXES)
-
-#define ALL_MATERIAL_BITS (FRONT_MATERIAL_BITS | BACK_MATERIAL_BITS)
-/*@}*/
-
-
-#define EXP_TABLE_SIZE 512 /**< Specular exponent lookup table sizes */
-#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */
-
-/**
- * Material shininess lookup table.
- */
-struct gl_shine_tab
-{
- struct gl_shine_tab *next, *prev;
- GLfloat tab[SHINE_TABLE_SIZE+1];
- GLfloat shininess;
- GLuint refcount;
-};
-
-
-/**
- * Light source state.
- */
-struct gl_light
-{
- struct gl_light *next; /**< double linked list with sentinel */
- struct gl_light *prev;
-
- GLfloat Ambient[4]; /**< ambient color */
- GLfloat Diffuse[4]; /**< diffuse color */
- GLfloat Specular[4]; /**< specular color */
- GLfloat EyePosition[4]; /**< position in eye coordinates */
- GLfloat SpotDirection[4]; /**< spotlight direction in eye coordinates */
- GLfloat SpotExponent;
- GLfloat SpotCutoff; /**< in degrees */
- GLfloat _CosCutoffNeg; /**< = cos(SpotCutoff) */
- GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
- GLfloat ConstantAttenuation;
- GLfloat LinearAttenuation;
- GLfloat QuadraticAttenuation;
- GLboolean Enabled; /**< On/off flag */
-
- /**
- * \name Derived fields
- */
- /*@{*/
- GLbitfield _Flags; /**< State */
-
- GLfloat _Position[4]; /**< position in eye/obj coordinates */
- GLfloat _VP_inf_norm[3]; /**< Norm direction to infinite light */
- GLfloat _h_inf_norm[3]; /**< Norm( _VP_inf_norm + <0,0,1> ) */
- GLfloat _NormSpotDirection[4]; /**< normalized spotlight direction */
- GLfloat _VP_inf_spot_attenuation;
-
- GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /**< to replace a pow() call */
- GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */
- GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */
- GLfloat _MatSpecular[2][3]; /**< material spec * light specular */
- GLfloat _dli; /**< CI diffuse light intensity */
- GLfloat _sli; /**< CI specular light intensity */
- /*@}*/
-};
-
-
-/**
- * Light model state.
- */
-struct gl_lightmodel
-{
- GLfloat Ambient[4]; /**< ambient color */
- GLboolean LocalViewer; /**< Local (or infinite) view point? */
- GLboolean TwoSide; /**< Two (or one) sided lighting? */
- GLenum ColorControl; /**< either GL_SINGLE_COLOR
- * or GL_SEPARATE_SPECULAR_COLOR */
-};
-
-
-/**
- * Material state.
- */
-struct gl_material
-{
- GLfloat Attrib[MAT_ATTRIB_MAX][4];
-};
-
-
-/**
- * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT)
- */
-struct gl_accum_attrib
-{
- GLfloat ClearColor[4]; /**< Accumulation buffer clear color */
-};
-
-
-/**
- * Color buffer attribute group (GL_COLOR_BUFFER_BIT).
- */
-struct gl_colorbuffer_attrib
-{
- GLuint ClearIndex; /**< Index to use for glClear */
- GLclampf ClearColor[4]; /**< Color to use for glClear */
-
- GLuint IndexMask; /**< Color index write mask */
- GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */
-
- GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */
-
- /**
- * \name alpha testing
- */
- /*@{*/
- GLboolean AlphaEnabled; /**< Alpha test enabled flag */
- GLenum AlphaFunc; /**< Alpha test function */
- GLclampf AlphaRef; /**< Alpha reference value */
- /*@}*/
-
- /**
- * \name Blending
- */
- /*@{*/
- GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */
- GLfloat BlendColor[4]; /**< Blending color */
- struct
- {
- GLenum SrcRGB; /**< RGB blend source term */
- GLenum DstRGB; /**< RGB blend dest term */
- GLenum SrcA; /**< Alpha blend source term */
- GLenum DstA; /**< Alpha blend dest term */
- GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
- GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
- } Blend[MAX_DRAW_BUFFERS];
- /** Are the blend func terms currently different for each buffer/target? */
- GLboolean _BlendFuncPerBuffer;
- /** Are the blend equations currently different for each buffer/target? */
- GLboolean _BlendEquationPerBuffer;
- /*@}*/
-
- /**
- * \name Logic op
- */
- /*@{*/
- GLenum LogicOp; /**< Logic operator */
- GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */
- GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */
- GLboolean _LogicOpEnabled; /**< RGBA logic op + EXT_blend_logic_op enabled flag */
- /*@}*/
-
- GLboolean DitherFlag; /**< Dither enable flag */
-
- GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
- GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
-};
-
-
-/**
- * Current attribute group (GL_CURRENT_BIT).
- */
-struct gl_current_attrib
-{
- /**
- * \name Current vertex attributes.
- * \note Values are valid only after FLUSH_VERTICES has been called.
- * \note Index and Edgeflag current values are stored as floats in the
- * SIX and SEVEN attribute slots.
- */
- GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */
-
- /**
- * \name Current raster position attributes (always valid).
- * \note This set of attributes is very similar to the SWvertex struct.
- */
- /*@{*/
- GLfloat RasterPos[4];
- GLfloat RasterDistance;
- GLfloat RasterColor[4];
- GLfloat RasterSecondaryColor[4];
- GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4];
- GLboolean RasterPosValid;
- /*@}*/
-};
-
-
-/**
- * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT).
- */
-struct gl_depthbuffer_attrib
-{
- GLenum Func; /**< Function for depth buffer compare */
- GLclampd Clear; /**< Value to clear depth buffer to */
- GLboolean Test; /**< Depth buffering enabled flag */
- GLboolean Mask; /**< Depth buffer writable? */
- GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */
- GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */
-};
-
-
-/**
- * Evaluator attribute group (GL_EVAL_BIT).
- */
-struct gl_eval_attrib
-{
- /**
- * \name Enable bits
- */
- /*@{*/
- GLboolean Map1Color4;
- GLboolean Map1Index;
- GLboolean Map1Normal;
- GLboolean Map1TextureCoord1;
- GLboolean Map1TextureCoord2;
- GLboolean Map1TextureCoord3;
- GLboolean Map1TextureCoord4;
- GLboolean Map1Vertex3;
- GLboolean Map1Vertex4;
- GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */
- GLboolean Map2Color4;
- GLboolean Map2Index;
- GLboolean Map2Normal;
- GLboolean Map2TextureCoord1;
- GLboolean Map2TextureCoord2;
- GLboolean Map2TextureCoord3;
- GLboolean Map2TextureCoord4;
- GLboolean Map2Vertex3;
- GLboolean Map2Vertex4;
- GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */
- GLboolean AutoNormal;
- /*@}*/
-
- /**
- * \name Map Grid endpoints and divisions and calculated du values
- */
- /*@{*/
- GLint MapGrid1un;
- GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du;
- GLint MapGrid2un, MapGrid2vn;
- GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du;
- GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv;
- /*@}*/
-};
-
-
-/**
- * Fog attribute group (GL_FOG_BIT).
- */
-struct gl_fog_attrib
-{
- GLboolean Enabled; /**< Fog enabled flag */
- GLfloat Color[4]; /**< Fog color */
- GLfloat Density; /**< Density >= 0.0 */
- GLfloat Start; /**< Start distance in eye coords */
- GLfloat End; /**< End distance in eye coords */
- GLfloat Index; /**< Fog index */
- GLenum Mode; /**< Fog mode */
- GLboolean ColorSumEnabled;
- GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */
- GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */
-};
-
-
-/**
- * Hint attribute group (GL_HINT_BIT).
- *
- * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE.
- */
-struct gl_hint_attrib
-{
- GLenum PerspectiveCorrection;
- GLenum PointSmooth;
- GLenum LineSmooth;
- GLenum PolygonSmooth;
- GLenum Fog;
- GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */
- GLenum TextureCompression; /**< GL_ARB_texture_compression */
- GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */
-};
-
-/**
- * Light state flags.
- */
-/*@{*/
-#define LIGHT_SPOT 0x1
-#define LIGHT_LOCAL_VIEWER 0x2
-#define LIGHT_POSITIONAL 0x4
-#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER)
-/*@}*/
-
-
-/**
- * Lighting attribute group (GL_LIGHT_BIT).
- */
-struct gl_light_attrib
-{
- struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */
- struct gl_lightmodel Model; /**< Lighting model */
-
- /**
- * Must flush FLUSH_VERTICES before referencing:
- */
- /*@{*/
- struct gl_material Material; /**< Includes front & back values */
- /*@}*/
-
- GLboolean Enabled; /**< Lighting enabled flag */
- GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */
- GLenum ProvokingVertex; /**< GL_EXT_provoking_vertex */
- GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */
- GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */
- GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */
- GLboolean ColorMaterialEnabled;
- GLenum ClampVertexColor;
-
- struct gl_light EnabledList; /**< List sentinel */
-
- /**
- * Derived state for optimizations:
- */
- /*@{*/
- GLboolean _NeedEyeCoords;
- GLboolean _NeedVertices; /**< Use fast shader? */
- GLbitfield _Flags; /**< LIGHT_* flags, see above */
- GLfloat _BaseColor[2][3];
- /*@}*/
-};
-
-
-/**
- * Line attribute group (GL_LINE_BIT).
- */
-struct gl_line_attrib
-{
- GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */
- GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */
- GLushort StipplePattern; /**< Stipple pattern */
- GLint StippleFactor; /**< Stipple repeat factor */
- GLfloat Width; /**< Line width */
-};
-
-
-/**
- * Display list attribute group (GL_LIST_BIT).
- */
-struct gl_list_attrib
-{
- GLuint ListBase;
-};
-
-
-/**
- * Multisample attribute group (GL_MULTISAMPLE_BIT).
- */
-struct gl_multisample_attrib
-{
- GLboolean Enabled;
- GLboolean _Enabled; /**< true if Enabled and multisample buffer */
- GLboolean SampleAlphaToCoverage;
- GLboolean SampleAlphaToOne;
- GLboolean SampleCoverage;
- GLfloat SampleCoverageValue;
- GLboolean SampleCoverageInvert;
-};
-
-
-/**
- * A pixelmap (see glPixelMap)
- */
-struct gl_pixelmap
-{
- GLint Size;
- GLfloat Map[MAX_PIXEL_MAP_TABLE];
- GLubyte Map8[MAX_PIXEL_MAP_TABLE]; /**< converted to 8-bit color */
-};
-
-
-/**
- * Collection of all pixelmaps
- */
-struct gl_pixelmaps
-{
- struct gl_pixelmap RtoR; /**< i.e. GL_PIXEL_MAP_R_TO_R */
- struct gl_pixelmap GtoG;
- struct gl_pixelmap BtoB;
- struct gl_pixelmap AtoA;
- struct gl_pixelmap ItoR;
- struct gl_pixelmap ItoG;
- struct gl_pixelmap ItoB;
- struct gl_pixelmap ItoA;
- struct gl_pixelmap ItoI;
- struct gl_pixelmap StoS;
-};
-
-
-/**
- * Pixel attribute group (GL_PIXEL_MODE_BIT).
- */
-struct gl_pixel_attrib
-{
- GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */
-
- /*--- Begin Pixel Transfer State ---*/
- /* Fields are in the order in which they're applied... */
-
- /** Scale & Bias (index shift, offset) */
- /*@{*/
- GLfloat RedBias, RedScale;
- GLfloat GreenBias, GreenScale;
- GLfloat BlueBias, BlueScale;
- GLfloat AlphaBias, AlphaScale;
- GLfloat DepthBias, DepthScale;
- GLint IndexShift, IndexOffset;
- /*@}*/
-
- /* Pixel Maps */
- /* Note: actual pixel maps are not part of this attrib group */
- GLboolean MapColorFlag;
- GLboolean MapStencilFlag;
-
- /*--- End Pixel Transfer State ---*/
-
- /** glPixelZoom */
- GLfloat ZoomX, ZoomY;
-
- /** GL_SGI_texture_color_table */
- GLfloat TextureColorTableScale[4]; /**< RGBA */
- GLfloat TextureColorTableBias[4]; /**< RGBA */
-};
-
-
-/**
- * Point attribute group (GL_POINT_BIT).
- */
-struct gl_point_attrib
-{
- GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */
- GLfloat Size; /**< User-specified point size */
- GLfloat Params[3]; /**< GL_EXT_point_parameters */
- GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */
- GLfloat Threshold; /**< GL_EXT_point_parameters */
- GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */
- GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */
- GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/
- GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */
- GLenum SpriteOrigin; /**< GL_ARB_point_sprite */
-};
-
-
-/**
- * Polygon attribute group (GL_POLYGON_BIT).
- */
-struct gl_polygon_attrib
-{
- GLenum FrontFace; /**< Either GL_CW or GL_CCW */
- GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
- GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
- GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */
- GLboolean CullFlag; /**< Culling on/off flag */
- GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */
- GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */
- GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */
- GLfloat OffsetFactor; /**< Polygon offset factor, from user */
- GLfloat OffsetUnits; /**< Polygon offset units, from user */
- GLboolean OffsetPoint; /**< Offset in GL_POINT mode */
- GLboolean OffsetLine; /**< Offset in GL_LINE mode */
- GLboolean OffsetFill; /**< Offset in GL_FILL mode */
-};
-
-
-/**
- * Scissor attributes (GL_SCISSOR_BIT).
- */
-struct gl_scissor_attrib
-{
- GLboolean Enabled; /**< Scissor test enabled? */
- GLint X, Y; /**< Lower left corner of box */
- GLsizei Width, Height; /**< Size of box */
-};
-
-
-/**
- * Stencil attribute group (GL_STENCIL_BUFFER_BIT).
- *
- * Three sets of stencil data are tracked so that OpenGL 2.0,
- * GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported
- * simultaneously. In each of the stencil state arrays, element 0 corresponds
- * to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 /
- * GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the
- * GL_EXT_stencil_two_side GL_BACK state.
- *
- * The derived value \c _BackFace is either 1 or 2 depending on whether or
- * not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled.
- *
- * The derived value \c _TestTwoSide is set when the front-face and back-face
- * stencil state are different.
- */
-struct gl_stencil_attrib
-{
- GLboolean Enabled; /**< Enabled flag */
- GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
- GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */
- GLboolean _Enabled; /**< Enabled and stencil buffer present */
- GLboolean _TestTwoSide;
- GLubyte _BackFace; /**< Current back stencil state (1 or 2) */
- GLenum Function[3]; /**< Stencil function */
- GLenum FailFunc[3]; /**< Fail function */
- GLenum ZPassFunc[3]; /**< Depth buffer pass function */
- GLenum ZFailFunc[3]; /**< Depth buffer fail function */
- GLint Ref[3]; /**< Reference value */
- GLuint ValueMask[3]; /**< Value mask */
- GLuint WriteMask[3]; /**< Write mask */
- GLuint Clear; /**< Clear value */
-};
-
-
-/**
- * An index for each type of texture object. These correspond to the GL
- * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc.
- * Note: the order is from highest priority to lowest priority.
- */
-typedef enum
-{
- TEXTURE_2D_ARRAY_INDEX,
- TEXTURE_1D_ARRAY_INDEX,
- TEXTURE_CUBE_INDEX,
- TEXTURE_3D_INDEX,
- TEXTURE_RECT_INDEX,
- TEXTURE_2D_INDEX,
- TEXTURE_1D_INDEX,
- NUM_TEXTURE_TARGETS
-} gl_texture_index;
-
-
-/**
- * Bit flags for each type of texture object
- * Used for Texture.Unit[]._ReallyEnabled flags.
- */
-/*@{*/
-#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX)
-#define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX)
-#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX)
-#define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX)
-#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX)
-#define TEXTURE_2D_BIT (1 << TEXTURE_2D_INDEX)
-#define TEXTURE_1D_BIT (1 << TEXTURE_1D_INDEX)
-/*@}*/
-
-
-/**
- * TexGenEnabled flags.
- */
-/*@{*/
-#define S_BIT 1
-#define T_BIT 2
-#define R_BIT 4
-#define Q_BIT 8
-#define STR_BITS (S_BIT | T_BIT | R_BIT)
-/*@}*/
-
-
-/**
- * Bit flag versions of the corresponding GL_ constants.
- */
-/*@{*/
-#define TEXGEN_SPHERE_MAP 0x1
-#define TEXGEN_OBJ_LINEAR 0x2
-#define TEXGEN_EYE_LINEAR 0x4
-#define TEXGEN_REFLECTION_MAP_NV 0x8
-#define TEXGEN_NORMAL_MAP_NV 0x10
-
-#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \
- TEXGEN_REFLECTION_MAP_NV | \
- TEXGEN_NORMAL_MAP_NV)
-#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \
- TEXGEN_REFLECTION_MAP_NV | \
- TEXGEN_NORMAL_MAP_NV | \
- TEXGEN_EYE_LINEAR)
-/*@}*/
-
-
-
-/** Tex-gen enabled for texture unit? */
-#define ENABLE_TEXGEN(unit) (1 << (unit))
-
-/** Non-identity texture matrix for texture unit? */
-#define ENABLE_TEXMAT(unit) (1 << (unit))
-
-
-/**
- * Texel fetch function prototype. We use texel fetch functions to
- * extract RGBA, color indexes and depth components out of 1D, 2D and 3D
- * texture images. These functions help to isolate us from the gritty
- * details of all the various texture image encodings.
- *
- * \param texImage texture image.
- * \param col texel column.
- * \param row texel row.
- * \param img texel image level/layer.
- * \param texelOut output texel (up to 4 GLchans)
- */
-typedef void (*FetchTexelFuncC)( const struct gl_texture_image *texImage,
- GLint col, GLint row, GLint img,
- GLchan *texelOut );
-
-/**
- * As above, but returns floats.
- * Used for depth component images and for upcoming signed/float
- * texture images.
- */
-typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage,
- GLint col, GLint row, GLint img,
- GLfloat *texelOut );
-
-
-typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage,
- GLint col, GLint row, GLint img,
- const void *texel);
-
-
-/**
- * Texture image state. Describes the dimensions of a texture image,
- * the texel format and pointers to Texel Fetch functions.
- */
-struct gl_texture_image
-{
- GLint InternalFormat; /**< Internal format as given by the user */
- GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA,
- * GL_LUMINANCE, GL_LUMINANCE_ALPHA,
- * GL_INTENSITY, GL_COLOR_INDEX,
- * GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT
- * only. Used for choosing TexEnv arithmetic.
- */
- GLuint TexFormat; /**< The actual format: MESA_FORMAT_x */
-
- GLuint Border; /**< 0 or 1 */
- GLuint Width; /**< = 2^WidthLog2 + 2*Border */
- GLuint Height; /**< = 2^HeightLog2 + 2*Border */
- GLuint Depth; /**< = 2^DepthLog2 + 2*Border */
- GLuint Width2; /**< = Width - 2*Border */
- GLuint Height2; /**< = Height - 2*Border */
- GLuint Depth2; /**< = Depth - 2*Border */
- GLuint WidthLog2; /**< = log2(Width2) */
- GLuint HeightLog2; /**< = log2(Height2) */
- GLuint DepthLog2; /**< = log2(Depth2) */
- GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */
- GLfloat WidthScale; /**< used for mipmap LOD computation */
- GLfloat HeightScale; /**< used for mipmap LOD computation */
- GLfloat DepthScale; /**< used for mipmap LOD computation */
- GLboolean IsClientData; /**< Data owned by client? */
- GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */
-
- struct gl_texture_object *TexObject; /**< Pointer back to parent object */
-
- FetchTexelFuncC FetchTexelc; /**< GLchan texel fetch function pointer */
- FetchTexelFuncF FetchTexelf; /**< Float texel fetch function pointer */
-
- GLuint RowStride; /**< Padded width in units of texels */
- GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
- each 2D slice in 'Data', in texels */
- GLvoid *Data; /**< Image data, accessed via FetchTexel() */
-
- /**
- * \name For device driver:
- */
- /*@{*/
- void *DriverData; /**< Arbitrary device driver data */
- /*@}*/
-};
-
-
-/**
- * Indexes for cube map faces.
- */
-typedef enum
-{
- FACE_POS_X = 0,
- FACE_NEG_X = 1,
- FACE_POS_Y = 2,
- FACE_NEG_Y = 3,
- FACE_POS_Z = 4,
- FACE_NEG_Z = 5,
- MAX_FACES = 6
-} gl_face_index;
-
-
-/**
- * Texture object state. Contains the array of mipmap images, border color,
- * wrap modes, filter modes, shadow/texcompare state, and the per-texture
- * color palette.
- */
-struct gl_texture_object
-{
- _glthread_Mutex Mutex; /**< for thread safety */
- GLint RefCount; /**< reference count */
- GLuint Name; /**< the user-visible texture object ID */
- GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
- GLfloat Priority; /**< in [0,1] */
- union {
- GLfloat f[4];
- GLuint ui[4];
- GLint i[4];
- } BorderColor; /**< Interpreted according to texture format */
- GLenum WrapS; /**< S-axis texture image wrap mode */
- GLenum WrapT; /**< T-axis texture image wrap mode */
- GLenum WrapR; /**< R-axis texture image wrap mode */
- GLenum MinFilter; /**< minification filter */
- GLenum MagFilter; /**< magnification filter */
- GLfloat MinLod; /**< min lambda, OpenGL 1.2 */
- GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */
- GLfloat LodBias; /**< OpenGL 1.4 */
- GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
- GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
- GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
- GLenum CompareMode; /**< GL_ARB_shadow */
- GLenum CompareFunc; /**< GL_ARB_shadow */
- GLfloat CompareFailValue; /**< GL_ARB_shadow_ambient */
- GLenum DepthMode; /**< GL_ARB_depth_texture */
- GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
- GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
- GLint CropRect[4]; /**< GL_OES_draw_texture */
- GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */
- GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */
- GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLboolean _Complete; /**< Is texture object complete? */
- GLboolean _RenderToTexture; /**< Any rendering to this texture? */
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
- GLenum sRGBDecode;
-
- /** Actual texture images, indexed by [cube face] and [mipmap level] */
- struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
-
- /** GL_EXT_paletted_texture */
- struct gl_color_table Palette;
-
- /**
- * \name For device driver.
- * Note: instead of attaching driver data to this pointer, it's preferable
- * to instead use this struct as a base class for your own texture object
- * class. Driver->NewTextureObject() can be used to implement the
- * allocation.
- */
- void *DriverData; /**< Arbitrary device driver data */
-};
-
-
-/** Up to four combiner sources are possible with GL_NV_texture_env_combine4 */
-#define MAX_COMBINER_TERMS 4
-
-
-/**
- * Texture combine environment state.
- */
-struct gl_tex_env_combine_state
-{
- GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
- GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
- /** Source terms: GL_PRIMARY_COLOR, GL_TEXTURE, etc */
- GLenum SourceRGB[MAX_COMBINER_TERMS];
- GLenum SourceA[MAX_COMBINER_TERMS];
- /** Source operands: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, etc */
- GLenum OperandRGB[MAX_COMBINER_TERMS];
- GLenum OperandA[MAX_COMBINER_TERMS];
- GLuint ScaleShiftRGB; /**< 0, 1 or 2 */
- GLuint ScaleShiftA; /**< 0, 1 or 2 */
- GLuint _NumArgsRGB; /**< Number of inputs used for the RGB combiner */
- GLuint _NumArgsA; /**< Number of inputs used for the A combiner */
-};
-
-
-/**
- * Texture coord generation state.
- */
-struct gl_texgen
-{
- GLenum Mode; /**< GL_EYE_LINEAR, GL_SPHERE_MAP, etc */
- GLbitfield _ModeBit; /**< TEXGEN_x bit corresponding to Mode */
- GLfloat ObjectPlane[4];
- GLfloat EyePlane[4];
-};
-
-
-/**
- * Texture unit state. Contains enable flags, texture environment/function/
- * combiners, texgen state, pointers to current texture objects and
- * post-filter color tables.
- */
-struct gl_texture_unit
-{
- GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */
- GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */
-
- GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */
- GLfloat EnvColor[4];
-
- struct gl_texgen GenS;
- struct gl_texgen GenT;
- struct gl_texgen GenR;
- struct gl_texgen GenQ;
- GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */
- GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */
-
- GLfloat LodBias; /**< for biasing mipmap levels */
- GLenum BumpTarget;
- GLfloat RotMatrix[4]; /* 2x2 matrix */
-
- /**
- * \name GL_EXT_texture_env_combine
- */
- struct gl_tex_env_combine_state Combine;
-
- /**
- * Derived state based on \c EnvMode and the \c BaseFormat of the
- * currently enabled texture.
- */
- struct gl_tex_env_combine_state _EnvMode;
-
- /**
- * Currently enabled combiner state. This will point to either
- * \c Combine or \c _EnvMode.
- */
- struct gl_tex_env_combine_state *_CurrentCombine;
-
- /** Current texture object pointers */
- struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS];
-
- /** Points to highest priority, complete and enabled texture object */
- struct gl_texture_object *_Current;
-
- /** GL_SGI_texture_color_table */
- /*@{*/
- struct gl_color_table ColorTable;
- struct gl_color_table ProxyColorTable;
- GLboolean ColorTableEnabled;
- /*@}*/
-};
-
-
-/**
- * Texture attribute group (GL_TEXTURE_BIT).
- */
-struct gl_texture_attrib
-{
- GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */
- struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
- struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS];
-
- /** GL_ARB_seamless_cubemap */
- GLboolean CubeMapSeamless;
-
- /** GL_EXT_shared_texture_palette */
- GLboolean SharedPalette;
- struct gl_color_table Palette;
-
- /** Texture units/samplers used by vertex or fragment texturing */
- GLbitfield _EnabledUnits;
-
- /** Texture coord units/sets used for fragment texturing */
- GLbitfield _EnabledCoordUnits;
-
- /** Texture coord units that have texgen enabled */
- GLbitfield _TexGenEnabled;
-
- /** Texture coord units that have non-identity matrices */
- GLbitfield _TexMatEnabled;
-
- /** Bitwise-OR of all Texture.Unit[i]._GenFlags */
- GLbitfield _GenFlags;
-};
-
-
-/**
- * Transformation attribute group (GL_TRANSFORM_BIT).
- */
-struct gl_transform_attrib
-{
- GLenum MatrixMode; /**< Matrix mode */
- GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; /**< User clip planes */
- GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /**< derived */
- GLbitfield ClipPlanesEnabled; /**< on/off bitmask */
- GLboolean Normalize; /**< Normalize all normals? */
- GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */
- GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */
- GLboolean DepthClamp; /**< GL_ARB_depth_clamp */
-
- GLfloat CullEyePos[4];
- GLfloat CullObjPos[4];
-};
-
-
-/**
- * Viewport attribute group (GL_VIEWPORT_BIT).
- */
-struct gl_viewport_attrib
-{
- GLint X, Y; /**< position */
- GLsizei Width, Height; /**< size */
- GLfloat Near, Far; /**< Depth buffer range */
- GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */
-};
-
-
-/**
- * GL_ARB_vertex/pixel_buffer_object buffer object
- */
-struct gl_buffer_object
-{
- _glthread_Mutex Mutex;
- GLint RefCount;
- GLuint Name;
- GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */
- GLsizeiptrARB Size; /**< Size of buffer storage in bytes */
- GLubyte *Data; /**< Location of storage either in RAM or VRAM. */
- /** Fields describing a mapped buffer */
- /*@{*/
- GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */
- GLvoid *Pointer; /**< User-space address of mapping */
- GLintptr Offset; /**< Mapped offset */
- GLsizeiptr Length; /**< Mapped length */
- /*@}*/
- GLboolean Written; /**< Ever written to? (for debugging) */
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
-};
-
-
-/**
- * Client pixel packing/unpacking attributes
- */
-struct gl_pixelstore_attrib
-{
- GLint Alignment;
- GLint RowLength;
- GLint SkipPixels;
- GLint SkipRows;
- GLint ImageHeight;
- GLint SkipImages;
- GLboolean SwapBytes;
- GLboolean LsbFirst;
- GLboolean ClientStorage; /**< GL_APPLE_client_storage */
- GLboolean Invert; /**< GL_MESA_pack_invert */
- struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */
-};
-
-
-/**
- * Client vertex array attributes
- */
-struct gl_client_array
-{
- GLint Size; /**< components per element (1,2,3,4) */
- GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */
- GLenum Format; /**< default: GL_RGBA, but may be GL_BGRA */
- GLsizei Stride; /**< user-specified stride */
- GLsizei StrideB; /**< actual stride in bytes */
- const GLubyte *Ptr; /**< Points to array data */
- GLboolean Enabled; /**< Enabled flag is a boolean */
- GLboolean Normalized; /**< GL_ARB_vertex_program */
- GLboolean Integer; /**< Integer-valued? */
- GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
- GLuint _ElementSize; /**< size of each element in bytes */
-
- struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */
- GLuint _MaxElement; /**< max element index into array buffer + 1 */
-};
-
-
-/**
- * Collection of vertex arrays. Defined by the GL_APPLE_vertex_array_object
- * extension, but a nice encapsulation in any case.
- */
-struct gl_array_object
-{
- /** Name of the array object as received from glGenVertexArrayAPPLE. */
- GLuint Name;
-
- GLint RefCount;
- _glthread_Mutex Mutex;
- GLboolean VBOonly; /**< require all arrays to live in VBOs? */
-
- /** Conventional vertex arrays */
- /*@{*/
- struct gl_client_array Vertex;
- struct gl_client_array Weight;
- struct gl_client_array Normal;
- struct gl_client_array Color;
- struct gl_client_array SecondaryColor;
- struct gl_client_array FogCoord;
- struct gl_client_array Index;
- struct gl_client_array EdgeFlag;
- struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS];
- struct gl_client_array PointSize;
- /*@}*/
-
- /**
- * Generic arrays for vertex programs/shaders.
- * For NV vertex programs, these attributes alias and take priority
- * over the conventional attribs above. For ARB vertex programs and
- * GLSL vertex shaders, these attributes are separate.
- */
- struct gl_client_array VertexAttrib[MAX_VERTEX_GENERIC_ATTRIBS];
-
- /** Mask of _NEW_ARRAY_* values indicating which arrays are enabled */
- GLbitfield _Enabled;
-
- /**
- * Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs
- * we can determine the max legal (in bounds) glDrawElements array index.
- */
- GLuint _MaxElement;
-};
-
-
-/**
- * Vertex array state
- */
-struct gl_array_attrib
-{
- /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */
- struct gl_array_object *ArrayObj;
-
- /** The default vertex array object */
- struct gl_array_object *DefaultArrayObj;
-
- /** Array objects (GL_ARB/APPLE_vertex_array_object) */
- struct _mesa_HashTable *Objects;
-
- GLint ActiveTexture; /**< Client Active Texture */
- GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */
- GLuint LockCount; /**< GL_EXT_compiled_vertex_array */
-
- /** GL 3.1 (slightly different from GL_NV_primitive_restart) */
- GLboolean PrimitiveRestart;
- GLuint RestartIndex;
-
- GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */
-
- /* GL_ARB_vertex_buffer_object */
- struct gl_buffer_object *ArrayBufferObj;
- struct gl_buffer_object *ElementArrayBufferObj;
-};
-
-
-/**
- * Feedback buffer state
- */
-struct gl_feedback
-{
- GLenum Type;
- GLbitfield _Mask; /**< FB_* bits */
- GLfloat *Buffer;
- GLuint BufferSize;
- GLuint Count;
-};
-
-
-/**
- * Selection buffer state
- */
-struct gl_selection
-{
- GLuint *Buffer; /**< selection buffer */
- GLuint BufferSize; /**< size of the selection buffer */
- GLuint BufferCount; /**< number of values in the selection buffer */
- GLuint Hits; /**< number of records in the selection buffer */
- GLuint NameStackDepth; /**< name stack depth */
- GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */
- GLboolean HitFlag; /**< hit flag */
- GLfloat HitMinZ; /**< minimum hit depth */
- GLfloat HitMaxZ; /**< maximum hit depth */
-};
-
-
-/**
- * 1-D Evaluator control points
- */
-struct gl_1d_map
-{
- GLuint Order; /**< Number of control points */
- GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */
- GLfloat *Points; /**< Points to contiguous control points */
-};
-
-
-/**
- * 2-D Evaluator control points
- */
-struct gl_2d_map
-{
- GLuint Uorder; /**< Number of control points in U dimension */
- GLuint Vorder; /**< Number of control points in V dimension */
- GLfloat u1, u2, du;
- GLfloat v1, v2, dv;
- GLfloat *Points; /**< Points to contiguous control points */
-};
-
-
-/**
- * All evaluator control point state
- */
-struct gl_evaluators
-{
- /**
- * \name 1-D maps
- */
- /*@{*/
- struct gl_1d_map Map1Vertex3;
- struct gl_1d_map Map1Vertex4;
- struct gl_1d_map Map1Index;
- struct gl_1d_map Map1Color4;
- struct gl_1d_map Map1Normal;
- struct gl_1d_map Map1Texture1;
- struct gl_1d_map Map1Texture2;
- struct gl_1d_map Map1Texture3;
- struct gl_1d_map Map1Texture4;
- struct gl_1d_map Map1Attrib[16]; /**< GL_NV_vertex_program */
- /*@}*/
-
- /**
- * \name 2-D maps
- */
- /*@{*/
- struct gl_2d_map Map2Vertex3;
- struct gl_2d_map Map2Vertex4;
- struct gl_2d_map Map2Index;
- struct gl_2d_map Map2Color4;
- struct gl_2d_map Map2Normal;
- struct gl_2d_map Map2Texture1;
- struct gl_2d_map Map2Texture2;
- struct gl_2d_map Map2Texture3;
- struct gl_2d_map Map2Texture4;
- struct gl_2d_map Map2Attrib[16]; /**< GL_NV_vertex_program */
- /*@}*/
-};
-
-
-/**
- * Names of the various vertex/fragment program register files, etc.
- *
- * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
- * All values should fit in a 4-bit field.
- *
- * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
- * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
- * be "uniform" variables since they can only be set outside glBegin/End.
- * They're also all stored in the same Parameters array.
- */
-typedef enum
-{
- PROGRAM_TEMPORARY, /**< machine->Temporary[] */
- PROGRAM_INPUT, /**< machine->Inputs[] */
- PROGRAM_OUTPUT, /**< machine->Outputs[] */
- PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */
- PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */
- PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */
- PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */
- PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */
- PROGRAM_CONSTANT, /**< gl_program->Parameters[] */
- PROGRAM_UNIFORM, /**< gl_program->Parameters[] */
- PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */
- PROGRAM_ADDRESS, /**< machine->AddressReg */
- PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */
- PROGRAM_SYSTEM_VALUE,/**< InstanceId, PrimitiveID, etc. */
- PROGRAM_UNDEFINED, /**< Invalid/TBD value */
- PROGRAM_FILE_MAX
-} gl_register_file;
-
-
-/**
- * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be
- * one of these values.
- */
-typedef enum
-{
- SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */
- SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */
- SYSTEM_VALUE_MAX /**< Number of values */
-} gl_system_value;
-
-
-/** Vertex and fragment instructions */
-struct prog_instruction;
-struct gl_program_parameter_list;
-struct gl_uniform_list;
-
-
-/**
- * Base class for any kind of program object
- */
-struct gl_program
-{
- GLuint Id;
- GLubyte *String; /**< Null-terminated program text */
- GLint RefCount;
- GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */
- GLenum Format; /**< String encoding format */
- GLboolean Resident;
-
- struct prog_instruction *Instructions;
-
- GLbitfield InputsRead; /**< Bitmask of which input regs are read */
- GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
- GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
- GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */
- GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
- GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */
- GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
- GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
-
-
- /** Named parameters, constants, etc. from program text */
- struct gl_program_parameter_list *Parameters;
- /** Numbered local parameters */
- GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
-
- /** Vertex/fragment shader varying vars */
- struct gl_program_parameter_list *Varying;
- /** Vertex program user-defined attributes */
- struct gl_program_parameter_list *Attributes;
-
- /** Map from sampler unit to texture unit (set by glUniform1i()) */
- GLubyte SamplerUnits[MAX_SAMPLERS];
- /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
- gl_texture_index SamplerTargets[MAX_SAMPLERS];
-
- /** Bitmask of which register files are read/written with indirect
- * addressing. Mask of (1 << PROGRAM_x) bits.
- */
- GLbitfield IndirectRegisterFiles;
-
- /** Logical counts */
- /*@{*/
- GLuint NumInstructions;
- GLuint NumTemporaries;
- GLuint NumParameters;
- GLuint NumAttributes;
- GLuint NumAddressRegs;
- GLuint NumAluInstructions;
- GLuint NumTexInstructions;
- GLuint NumTexIndirections;
- /*@}*/
- /** Native, actual h/w counts */
- /*@{*/
- GLuint NumNativeInstructions;
- GLuint NumNativeTemporaries;
- GLuint NumNativeParameters;
- GLuint NumNativeAttributes;
- GLuint NumNativeAddressRegs;
- GLuint NumNativeAluInstructions;
- GLuint NumNativeTexInstructions;
- GLuint NumNativeTexIndirections;
- /*@}*/
-};
-
-
-/** Vertex program object */
-struct gl_vertex_program
-{
- struct gl_program Base; /**< base class */
- GLboolean IsNVProgram; /**< is this a GL_NV_vertex_program program? */
- GLboolean IsPositionInvariant;
-};
-
-
-/** Geometry program object */
-struct gl_geometry_program
-{
- struct gl_program Base; /**< base class */
-
- GLint VerticesOut;
- GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
- GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
- GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
-};
-
-
-/** Fragment program object */
-struct gl_fragment_program
-{
- struct gl_program Base; /**< base class */
- GLenum FogOption;
- GLboolean UsesKill; /**< shader uses KIL instruction */
- GLboolean OriginUpperLeft;
- GLboolean PixelCenterInteger;
-};
-
-
-/**
- * State common to vertex and fragment programs.
- */
-struct gl_program_state
-{
- GLint ErrorPos; /* GL_PROGRAM_ERROR_POSITION_ARB/NV */
- const char *ErrorString; /* GL_PROGRAM_ERROR_STRING_ARB/NV */
-};
-
-
-/**
- * Context state for vertex programs.
- */
-struct gl_vertex_program_state
-{
- GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */
- GLboolean _Enabled; /**< Enabled and _valid_ user program? */
- GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
- GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
- struct gl_vertex_program *Current; /**< User-bound vertex program */
-
- /** Currently enabled and valid vertex program (including internal
- * programs, user-defined vertex programs and GLSL vertex shaders).
- * This is the program we must use when rendering.
- */
- struct gl_vertex_program *_Current;
-
- GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
-
- /* For GL_NV_vertex_program only: */
- GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4];
- GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4];
-
- /** Should fixed-function T&L be implemented with a vertex prog? */
- GLboolean _MaintainTnlProgram;
-
- /** Program to emulate fixed-function T&L (see above) */
- struct gl_vertex_program *_TnlProgram;
-
- /** Cache of fixed-function programs */
- struct gl_program_cache *Cache;
-
- GLboolean _Overriden;
-};
-
-
-/**
- * Context state for geometry programs.
- */
-struct gl_geometry_program_state
-{
- GLboolean Enabled; /**< GL_ARB_GEOMETRY_SHADER4 */
- GLboolean _Enabled; /**< Enabled and valid program? */
- struct gl_geometry_program *Current; /**< user-bound geometry program */
-
- /** Currently enabled and valid program (including internal programs
- * and compiled shader programs).
- */
- struct gl_geometry_program *_Current;
-
- GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
-
- /** Cache of fixed-function programs */
- struct gl_program_cache *Cache;
-};
-
-/**
- * Context state for fragment programs.
- */
-struct gl_fragment_program_state
-{
- GLboolean Enabled; /**< User-set fragment program enable flag */
- GLboolean _Enabled; /**< Enabled and _valid_ user program? */
- struct gl_fragment_program *Current; /**< User-bound fragment program */
-
- /** Currently enabled and valid fragment program (including internal
- * programs, user-defined fragment programs and GLSL fragment shaders).
- * This is the program we must use when rendering.
- */
- struct gl_fragment_program *_Current;
-
- GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
-
- /** Should fixed-function texturing be implemented with a fragment prog? */
- GLboolean _MaintainTexEnvProgram;
-
- /** Program to emulate fixed-function texture env/combine (see above) */
- struct gl_fragment_program *_TexEnvProgram;
-
- /** Cache of fixed-function programs */
- struct gl_program_cache *Cache;
-};
-
-
-/**
- * ATI_fragment_shader runtime state
- */
-#define ATI_FS_INPUT_PRIMARY 0
-#define ATI_FS_INPUT_SECONDARY 1
-
-struct atifs_instruction;
-struct atifs_setupinst;
-
-/**
- * ATI fragment shader
- */
-struct ati_fragment_shader
-{
- GLuint Id;
- GLint RefCount;
- struct atifs_instruction *Instructions[2];
- struct atifs_setupinst *SetupInst[2];
- GLfloat Constants[8][4];
- GLbitfield LocalConstDef; /**< Indicates which constants have been set */
- GLubyte numArithInstr[2];
- GLubyte regsAssigned[2];
- GLubyte NumPasses; /**< 1 or 2 */
- GLubyte cur_pass;
- GLubyte last_optype;
- GLboolean interpinp1;
- GLboolean isValid;
- GLuint swizzlerq;
-};
-
-/**
- * Context state for GL_ATI_fragment_shader
- */
-struct gl_ati_fragment_shader_state
-{
- GLboolean Enabled;
- GLboolean _Enabled; /**< enabled and valid shader? */
- GLboolean Compiling;
- GLfloat GlobalConstants[8][4];
- struct ati_fragment_shader *Current;
-};
-
-
-/**
- * Occlusion/timer query object.
- */
-struct gl_query_object
-{
- GLenum Target; /**< The query target, when active */
- GLuint Id; /**< hash table ID/name */
- GLuint64EXT Result; /**< the counter */
- GLboolean Active; /**< inside Begin/EndQuery */
- GLboolean Ready; /**< result is ready? */
-};
-
-
-/**
- * Context state for query objects.
- */
-struct gl_query_state
-{
- struct _mesa_HashTable *QueryObjects;
- struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */
- struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */
-
- /** GL_NV_conditional_render */
- struct gl_query_object *CondRenderQuery;
-
- /** GL_EXT_transform_feedback */
- struct gl_query_object *PrimitivesGenerated;
- struct gl_query_object *PrimitivesWritten;
-
- /** GL_ARB_timer_query */
- struct gl_query_object *TimeElapsed;
-
- GLenum CondRenderMode;
-};
-
-
-/** Sync object state */
-struct gl_sync_object {
- struct simple_node link;
- GLenum Type; /**< GL_SYNC_FENCE */
- GLuint Name; /**< Fence name */
- GLint RefCount; /**< Reference count */
- GLboolean DeletePending; /**< Object was deleted while there were still
- * live references (e.g., sync not yet finished)
- */
- GLenum SyncCondition;
- GLbitfield Flags; /**< Flags passed to glFenceSync */
- GLuint StatusFlag:1; /**< Has the sync object been signaled? */
-};
-
-
-/** Set by #pragma directives */
-struct gl_sl_pragmas
-{
- GLboolean IgnoreOptimize; /**< ignore #pragma optimize(on/off) ? */
- GLboolean IgnoreDebug; /**< ignore #pragma debug(on/off) ? */
- GLboolean Optimize; /**< defaults on */
- GLboolean Debug; /**< defaults off */
-};
-
-
-/**
- * A GLSL vertex or fragment shader object.
- */
-struct gl_shader
-{
- GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB (first field!) */
- GLuint Name; /**< AKA the handle */
- GLint RefCount; /**< Reference count */
- GLboolean DeletePending;
- GLboolean CompileStatus;
- GLboolean Main; /**< shader defines main() */
- GLboolean UnresolvedRefs;
- const GLchar *Source; /**< Source code string */
- GLuint SourceChecksum; /**< for debug/logging purposes */
- struct gl_program *Program; /**< Post-compile assembly code */
- GLchar *InfoLog;
- struct gl_sl_pragmas Pragmas;
-
- unsigned Version; /**< GLSL version used for linking */
-
- struct exec_list *ir;
- struct glsl_symbol_table *symbols;
-
- /** Shaders containing built-in functions that are used for linking. */
- struct gl_shader *builtins_to_link[16];
- unsigned num_builtins_to_link;
-};
-
-
-/**
- * A GLSL program object.
- * Basically a linked collection of vertex and fragment shaders.
- */
-struct gl_shader_program
-{
- GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */
- GLuint Name; /**< aka handle or ID */
- GLint RefCount; /**< Reference count */
- GLboolean DeletePending;
-
- GLuint NumShaders; /**< number of attached shaders */
- struct gl_shader **Shaders; /**< List of attached the shaders */
-
- /** User-defined attribute bindings (glBindAttribLocation) */
- struct gl_program_parameter_list *Attributes;
-
- /** Transform feedback varyings */
- struct {
- GLenum BufferMode;
- GLuint NumVarying;
- GLchar **VaryingNames; /**< Array [NumVarying] of char * */
- } TransformFeedback;
-
- /** Geometry shader state - copied into gl_geometry_program at link time */
- struct {
- GLint VerticesOut;
- GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
- GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
- GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
- } Geom;
-
- /* post-link info: */
- struct gl_vertex_program *VertexProgram; /**< Linked vertex program */
- struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
- struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */
- struct gl_uniform_list *Uniforms;
- struct gl_program_parameter_list *Varying;
- GLboolean LinkStatus; /**< GL_LINK_STATUS */
- GLboolean Validated;
- GLboolean _Used; /**< Ever used for drawing? */
- GLchar *InfoLog;
-
- unsigned Version; /**< GLSL version used for linking */
-
- /**
- * Per-stage shaders resulting from the first stage of linking.
- *
- * Set of linked shaders for this program. The array is accessed using the
- * \c MESA_SHADER_* defines. Entries for non-existent stages will be
- * \c NULL.
- */
- struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES];
-};
-
-
-#define GLSL_DUMP 0x1 /**< Dump shaders to stdout */
-#define GLSL_LOG 0x2 /**< Write shaders to files */
-#define GLSL_OPT 0x4 /**< Force optimizations (override pragmas) */
-#define GLSL_NO_OPT 0x8 /**< Force no optimizations (override pragmas) */
-#define GLSL_UNIFORMS 0x10 /**< Print glUniform calls */
-#define GLSL_NOP_VERT 0x20 /**< Force no-op vertex shaders */
-#define GLSL_NOP_FRAG 0x40 /**< Force no-op fragment shaders */
-#define GLSL_USE_PROG 0x80 /**< Log glUseProgram calls */
-
-
-/**
- * Context state for GLSL vertex/fragment shaders.
- */
-struct gl_shader_state
-{
- /**
- * Programs used for rendering
- *
- * There is a separate program set for each shader stage. If
- * GL_EXT_separate_shader_objects is not supported, each of these must point
- * to \c NULL or to the same program.
- */
- struct gl_shader_program *CurrentVertexProgram;
- struct gl_shader_program *CurrentGeometryProgram;
- struct gl_shader_program *CurrentFragmentProgram;
-
- /**
- * Program used by glUniform calls.
- *
- * Explicitly set by \c glUseProgram and \c glActiveProgramEXT.
- */
- struct gl_shader_program *ActiveProgram;
-
- void *MemPool;
-
- GLbitfield Flags; /**< Mask of GLSL_x flags */
-};
-
-/**
- * Compiler options for a single GLSL shaders type
- */
-struct gl_shader_compiler_options
-{
- /** Driver-selectable options: */
- GLboolean EmitCondCodes; /**< Use condition codes? */
- GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */
- /**
- * Attempts to flatten all ir_if (OPCODE_IF) for GPUs that can't
- * support control flow.
- */
- GLboolean EmitNoIfs;
- GLboolean EmitNoLoops;
- GLboolean EmitNoFunctions;
- GLboolean EmitNoCont; /**< Emit CONT opcode? */
- GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */
- GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */
- GLboolean EmitNoPow; /**< Emit POW opcodes? */
-
- /**
- * \name Forms of indirect addressing the driver cannot do.
- */
- /*@{*/
- GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */
- GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */
- GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */
- GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */
- /*@}*/
-
- GLuint MaxUnrollIterations;
-
- struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */
-};
-
-/**
- * Transform feedback object state
- */
-struct gl_transform_feedback_object
-{
- GLuint Name; /**< AKA the object ID */
- GLint RefCount;
- GLboolean Active; /**< Is transform feedback enabled? */
- GLboolean Paused; /**< Is transform feedback paused? */
-
- /** The feedback buffers */
- GLuint BufferNames[MAX_FEEDBACK_ATTRIBS];
- struct gl_buffer_object *Buffers[MAX_FEEDBACK_ATTRIBS];
-
- /** Start of feedback data in dest buffer */
- GLintptr Offset[MAX_FEEDBACK_ATTRIBS];
- /** Max data to put into dest buffer (in bytes) */
- GLsizeiptr Size[MAX_FEEDBACK_ATTRIBS];
-};
-
-
-/**
- * Context state for transform feedback.
- */
-struct gl_transform_feedback
-{
- GLenum Mode; /**< GL_POINTS, GL_LINES or GL_TRIANGLES */
-
- GLboolean RasterDiscard; /**< GL_RASTERIZER_DISCARD */
-
- /** The general binding point (GL_TRANSFORM_FEEDBACK_BUFFER) */
- struct gl_buffer_object *CurrentBuffer;
-
- /** The table of all transform feedback objects */
- struct _mesa_HashTable *Objects;
-
- /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */
- struct gl_transform_feedback_object *CurrentObject;
-
- /** The default xform-fb object (Name==0) */
- struct gl_transform_feedback_object *DefaultObject;
-};
-
-
-
-/**
- * State which can be shared by multiple contexts:
- */
-struct gl_shared_state
-{
- _glthread_Mutex Mutex; /**< for thread safety */
- GLint RefCount; /**< Reference count */
- struct _mesa_HashTable *DisplayList; /**< Display lists hash table */
- struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */
-
- /** Default texture objects (shared by all texture units) */
- struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
-
- /** Fallback texture used when a bound texture is incomplete */
- struct gl_texture_object *FallbackTex;
-
- /**
- * \name Thread safety and statechange notification for texture
- * objects.
- *
- * \todo Improve the granularity of locking.
- */
- /*@{*/
- _glthread_Mutex TexMutex; /**< texobj thread safety */
- GLuint TextureStateStamp; /**< state notification for shared tex */
- /*@}*/
-
- /** Default buffer object for vertex arrays that aren't in VBOs */
- struct gl_buffer_object *NullBufferObj;
-
- /**
- * \name Vertex/geometry/fragment programs
- */
- /*@{*/
- struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
- struct gl_vertex_program *DefaultVertexProgram;
- struct gl_fragment_program *DefaultFragmentProgram;
- struct gl_geometry_program *DefaultGeometryProgram;
- /*@}*/
-
- /* GL_ATI_fragment_shader */
- struct _mesa_HashTable *ATIShaders;
- struct ati_fragment_shader *DefaultFragmentShader;
-
- struct _mesa_HashTable *BufferObjects;
-
- /** Table of both gl_shader and gl_shader_program objects */
- struct _mesa_HashTable *ShaderObjects;
-
- /* GL_EXT_framebuffer_object */
- struct _mesa_HashTable *RenderBuffers;
- struct _mesa_HashTable *FrameBuffers;
-
- /* GL_ARB_sync */
- struct simple_node SyncObjects;
-
- void *DriverData; /**< Device driver shared state */
-};
-
-
-
-
-/**
- * A renderbuffer stores colors or depth values or stencil values.
- * A framebuffer object will have a collection of these.
- * Data are read/written to the buffer with a handful of Get/Put functions.
- *
- * Instances of this object are allocated with the Driver's NewRenderbuffer
- * hook. Drivers will likely wrap this class inside a driver-specific
- * class to simulate inheritance.
- */
-struct gl_renderbuffer
-{
-#define RB_MAGIC 0xaabbccdd
- int Magic; /** XXX TEMPORARY DEBUG INFO */
- _glthread_Mutex Mutex; /**< for thread safety */
- GLuint ClassID; /**< Useful for drivers */
- GLuint Name;
- GLint RefCount;
- GLuint Width, Height;
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
-
- GLenum InternalFormat; /**< The user-specified format */
- GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
- GL_STENCIL_INDEX. */
- GLuint Format; /**< The actual format: MESA_FORMAT_x */
-
- GLubyte NumSamples;
-
- GLenum DataType; /**< Type of values passed to the Get/Put functions */
- GLvoid *Data; /**< This may not be used by some kinds of RBs */
-
- /* Used to wrap one renderbuffer around another: */
- struct gl_renderbuffer *Wrapped;
-
- /* Delete this renderbuffer */
- void (*Delete)(struct gl_renderbuffer *rb);
-
- /* Allocate new storage for this renderbuffer */
- GLboolean (*AllocStorage)(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLenum internalFormat,
- GLuint width, GLuint height);
-
- /* Lock/Unlock are called before/after calling the Get/Put functions.
- * Not sure this is the right place for these yet.
- void (*Lock)(struct gl_context *ctx, struct gl_renderbuffer *rb);
- void (*Unlock)(struct gl_context *ctx, struct gl_renderbuffer *rb);
- */
-
- /* Return a pointer to the element/pixel at (x,y).
- * Should return NULL if the buffer memory can't be directly addressed.
- */
- void *(*GetPointer)(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLint x, GLint y);
-
- /* Get/Read a row of values.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*GetRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, void *values);
-
- /* Get/Read values at arbitrary locations.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*GetValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- const GLint x[], const GLint y[], void *values);
-
- /* Put/Write a row of values.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *values, const GLubyte *mask);
-
- /* Put/Write a row of RGB values. This is a special-case routine that's
- * only used for RGBA renderbuffers when the source data is GL_RGB. That's
- * a common case for glDrawPixels and some triangle routines.
- * The values will be of format GL_RGB and type DataType.
- */
- void (*PutRowRGB)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *values, const GLubyte *mask);
-
-
- /* Put/Write a row of identical values.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutMonoRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *value, const GLubyte *mask);
-
- /* Put/Write values at arbitrary locations.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- const GLint x[], const GLint y[], const void *values,
- const GLubyte *mask);
- /* Put/Write identical values at arbitrary locations.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutMonoValues)(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *value, const GLubyte *mask);
-};
-
-
-/**
- * A renderbuffer attachment points to either a texture object (and specifies
- * a mipmap level, cube face or 3D texture slice) or points to a renderbuffer.
- */
-struct gl_renderbuffer_attachment
-{
- GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */
- GLboolean Complete;
-
- /**
- * If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the
- * application supplied renderbuffer object.
- */
- struct gl_renderbuffer *Renderbuffer;
-
- /**
- * If \c Type is \c GL_TEXTURE, this stores a pointer to the application
- * supplied texture object.
- */
- struct gl_texture_object *Texture;
- GLuint TextureLevel; /**< Attached mipmap level. */
- GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */
- GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D
- * and 2D array textures */
-};
-
-
-/**
- * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc).
- * In C++ terms, think of this as a base class from which device drivers
- * will make derived classes.
- */
-struct gl_framebuffer
-{
- _glthread_Mutex Mutex; /**< for thread safety */
- /**
- * If zero, this is a window system framebuffer. If non-zero, this
- * is a FBO framebuffer; note that for some devices (i.e. those with
- * a natural pixel coordinate system for FBOs that differs from the
- * OpenGL/Mesa coordinate system), this means that the viewport,
- * polygon face orientation, and polygon stipple will have to be inverted.
- */
- GLuint Name;
-
- GLint RefCount;
- GLboolean DeletePending;
-
- /**
- * The framebuffer's visual. Immutable if this is a window system buffer.
- * Computed from attachments if user-made FBO.
- */
- struct gl_config Visual;
-
- GLboolean Initialized;
-
- GLuint Width, Height; /**< size of frame buffer in pixels */
-
- /** \name Drawing bounds (Intersection of buffer size and scissor box) */
- /*@{*/
- GLint _Xmin, _Xmax; /**< inclusive */
- GLint _Ymin, _Ymax; /**< exclusive */
- /*@}*/
-
- /** \name Derived Z buffer stuff */
- /*@{*/
- GLuint _DepthMax; /**< Max depth buffer value */
- GLfloat _DepthMaxF; /**< Float max depth buffer value */
- GLfloat _MRD; /**< minimum resolvable difference in Z values */
- /*@}*/
-
- /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
- GLenum _Status;
-
- /** Integer color values */
- GLboolean _IntegerColor;
-
- /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */
- struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT];
-
- /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER
- * attribute group and GL_PIXEL attribute group, respectively.
- */
- GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS];
- GLenum ColorReadBuffer;
-
- /** Computed from ColorDraw/ReadBuffer above */
- GLuint _NumColorDrawBuffers;
- GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */
- GLint _ColorReadBufferIndex; /* -1 = None */
- struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
- struct gl_renderbuffer *_ColorReadBuffer;
-
- /** The Actual depth/stencil buffers to use. May be wrappers around the
- * depth/stencil buffers attached above. */
- struct gl_renderbuffer *_DepthBuffer;
- struct gl_renderbuffer *_StencilBuffer;
-
- /** Delete this framebuffer */
- void (*Delete)(struct gl_framebuffer *fb);
-};
-
-
-/**
- * Limits for vertex and fragment programs/shaders.
- */
-struct gl_program_constants
-{
- /* logical limits */
- GLuint MaxInstructions;
- GLuint MaxAluInstructions;
- GLuint MaxTexInstructions;
- GLuint MaxTexIndirections;
- GLuint MaxAttribs;
- GLuint MaxTemps;
- GLuint MaxAddressRegs;
- GLuint MaxParameters;
- GLuint MaxLocalParams;
- GLuint MaxEnvParams;
- /* native/hardware limits */
- GLuint MaxNativeInstructions;
- GLuint MaxNativeAluInstructions;
- GLuint MaxNativeTexInstructions;
- GLuint MaxNativeTexIndirections;
- GLuint MaxNativeAttribs;
- GLuint MaxNativeTemps;
- GLuint MaxNativeAddressRegs;
- GLuint MaxNativeParameters;
- /* For shaders */
- GLuint MaxUniformComponents;
- /* GL_ARB_geometry_shader4 */
- GLuint MaxGeometryTextureImageUnits;
- GLuint MaxGeometryVaryingComponents;
- GLuint MaxVertexVaryingComponents;
- GLuint MaxGeometryUniformComponents;
- GLuint MaxGeometryOutputVertices;
- GLuint MaxGeometryTotalOutputComponents;
-};
-
-
-/**
- * Constants which may be overridden by device driver during context creation
- * but are never changed after that.
- */
-struct gl_constants
-{
- GLint MaxTextureMbytes; /**< Max memory per image, in MB */
- GLint MaxTextureLevels; /**< Max mipmap levels. */
- GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */
- GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */
- GLint MaxArrayTextureLayers; /**< Max layers in array textures */
- GLint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */
- GLuint MaxTextureCoordUnits;
- GLuint MaxTextureImageUnits;
- GLuint MaxVertexTextureImageUnits;
- GLuint MaxCombinedTextureImageUnits;
- GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */
- GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
- GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */
-
- GLuint MaxArrayLockSize;
-
- GLint SubPixelBits;
-
- GLfloat MinPointSize, MaxPointSize; /**< aliased */
- GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */
- GLfloat PointSizeGranularity;
- GLfloat MinLineWidth, MaxLineWidth; /**< aliased */
- GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */
- GLfloat LineWidthGranularity;
-
- GLuint MaxColorTableSize;
-
- GLuint MaxClipPlanes;
- GLuint MaxLights;
- GLfloat MaxShininess; /**< GL_NV_light_max_exponent */
- GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */
-
- GLuint MaxViewportWidth, MaxViewportHeight;
-
- struct gl_program_constants VertexProgram; /**< GL_ARB_vertex_program */
- struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */
- struct gl_program_constants GeometryProgram; /**< GL_ARB_geometry_shader4 */
- GLuint MaxProgramMatrices;
- GLuint MaxProgramMatrixStackDepth;
-
- /** vertex array / buffer object bounds checking */
- GLboolean CheckArrayBounds;
-
- GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */
-
- GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */
- GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */
- GLuint MaxSamples; /**< GL_ARB_framebuffer_object */
-
- GLuint MaxVarying; /**< Number of float[4] varying parameters */
-
- GLuint GLSLVersion; /**< GLSL version supported (ex: 120 = 1.20) */
-
- /** Which texture units support GL_ATI_envmap_bumpmap as targets */
- GLbitfield SupportedBumpUnits;
-
- /**
- * Maximum amount of time, measured in nanseconds, that the server can wait.
- */
- GLuint64 MaxServerWaitTimeout;
-
- /** GL_EXT_provoking_vertex */
- GLboolean QuadsFollowProvokingVertexConvention;
-
- /** OpenGL version 3.0 */
- GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */
-
- /** OpenGL version 3.2 */
- GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */
-
- /** GL_EXT_transform_feedback */
- GLuint MaxTransformFeedbackSeparateAttribs;
- GLuint MaxTransformFeedbackSeparateComponents;
- GLuint MaxTransformFeedbackInterleavedComponents;
-
- /** GL_EXT_gpu_shader4 */
- GLint MinProgramTexelOffset, MaxProgramTexelOffset;
-};
-
-
-/**
- * Enable flag for each OpenGL extension. Different device drivers will
- * enable different extensions at runtime.
- */
-struct gl_extensions
-{
- GLboolean dummy; /* don't remove this! */
- GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */
- GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
- GLboolean ARB_ES2_compatibility;
- GLboolean ARB_blend_func_extended;
- GLboolean ARB_copy_buffer;
- GLboolean ARB_depth_buffer_float;
- GLboolean ARB_depth_clamp;
- GLboolean ARB_depth_texture;
- GLboolean ARB_draw_buffers;
- GLboolean ARB_draw_buffers_blend;
- GLboolean ARB_draw_elements_base_vertex;
- GLboolean ARB_draw_instanced;
- GLboolean ARB_fragment_coord_conventions;
- GLboolean ARB_fragment_program;
- GLboolean ARB_fragment_program_shadow;
- GLboolean ARB_fragment_shader;
- GLboolean ARB_framebuffer_object;
- GLboolean ARB_explicit_attrib_location;
- GLboolean ARB_geometry_shader4;
- GLboolean ARB_half_float_pixel;
- GLboolean ARB_half_float_vertex;
- GLboolean ARB_instanced_arrays;
- GLboolean ARB_map_buffer_range;
- GLboolean ARB_multisample;
- GLboolean ARB_multitexture;
- GLboolean ARB_occlusion_query;
- GLboolean ARB_occlusion_query2;
- GLboolean ARB_point_sprite;
- GLboolean ARB_sampler_objects;
- GLboolean ARB_seamless_cube_map;
- GLboolean ARB_shader_objects;
- GLboolean ARB_shader_stencil_export;
- GLboolean ARB_shading_language_100;
- GLboolean ARB_shadow;
- GLboolean ARB_shadow_ambient;
- GLboolean ARB_sync;
- GLboolean ARB_texture_border_clamp;
- GLboolean ARB_texture_buffer_object;
- GLboolean ARB_texture_compression;
- GLboolean ARB_texture_compression_rgtc;
- GLboolean ARB_texture_cube_map;
- GLboolean ARB_texture_env_combine;
- GLboolean ARB_texture_env_crossbar;
- GLboolean ARB_texture_env_dot3;
- GLboolean ARB_texture_float;
- GLboolean ARB_texture_mirrored_repeat;
- GLboolean ARB_texture_multisample;
- GLboolean ARB_texture_non_power_of_two;
- GLboolean ARB_texture_rg;
- GLboolean ARB_texture_rgb10_a2ui;
- GLboolean ARB_timer_query;
- GLboolean ARB_transform_feedback2;
- GLboolean ARB_transpose_matrix;
- GLboolean ARB_uniform_buffer_object;
- GLboolean ARB_vertex_array_object;
- GLboolean ARB_vertex_buffer_object;
- GLboolean ARB_vertex_program;
- GLboolean ARB_vertex_shader;
- GLboolean ARB_vertex_type_2_10_10_10_rev;
- GLboolean ARB_window_pos;
- GLboolean EXT_abgr;
- GLboolean EXT_bgra;
- GLboolean EXT_blend_color;
- GLboolean EXT_blend_equation_separate;
- GLboolean EXT_blend_func_separate;
- GLboolean EXT_blend_logic_op;
- GLboolean EXT_blend_minmax;
- GLboolean EXT_blend_subtract;
- GLboolean EXT_clip_volume_hint;
- GLboolean EXT_compiled_vertex_array;
- GLboolean EXT_copy_texture;
- GLboolean EXT_depth_bounds_test;
- GLboolean EXT_draw_buffers2;
- GLboolean EXT_draw_range_elements;
- GLboolean EXT_fog_coord;
- GLboolean EXT_framebuffer_blit;
- GLboolean EXT_framebuffer_multisample;
- GLboolean EXT_framebuffer_object;
- GLboolean EXT_framebuffer_sRGB;
- GLboolean EXT_gpu_program_parameters;
- GLboolean EXT_gpu_shader4;
- GLboolean EXT_multi_draw_arrays;
- GLboolean EXT_paletted_texture;
- GLboolean EXT_packed_depth_stencil;
- GLboolean EXT_packed_float;
- GLboolean EXT_packed_pixels;
- GLboolean EXT_pixel_buffer_object;
- GLboolean EXT_point_parameters;
- GLboolean EXT_polygon_offset;
- GLboolean EXT_provoking_vertex;
- GLboolean EXT_rescale_normal;
- GLboolean EXT_shadow_funcs;
- GLboolean EXT_secondary_color;
- GLboolean EXT_separate_shader_objects;
- GLboolean EXT_separate_specular_color;
- GLboolean EXT_shared_texture_palette;
- GLboolean EXT_stencil_wrap;
- GLboolean EXT_stencil_two_side;
- GLboolean EXT_subtexture;
- GLboolean EXT_texture;
- GLboolean EXT_texture_object;
- GLboolean EXT_texture3D;
- GLboolean EXT_texture_array;
- GLboolean EXT_texture_compression_s3tc;
- GLboolean EXT_texture_env_add;
- GLboolean EXT_texture_env_combine;
- GLboolean EXT_texture_env_dot3;
- GLboolean EXT_texture_filter_anisotropic;
- GLboolean EXT_texture_integer;
- GLboolean EXT_texture_lod_bias;
- GLboolean EXT_texture_mirror_clamp;
- GLboolean EXT_texture_shared_exponent;
- GLboolean EXT_texture_sRGB;
- GLboolean EXT_texture_sRGB_decode;
- GLboolean EXT_texture_swizzle;
- GLboolean EXT_transform_feedback;
- GLboolean EXT_timer_query;
- GLboolean EXT_vertex_array;
- GLboolean EXT_vertex_array_bgra;
- GLboolean EXT_vertex_array_set;
- GLboolean OES_standard_derivatives;
- /* vendor extensions */
- GLboolean APPLE_client_storage;
- GLboolean APPLE_packed_pixels;
- GLboolean APPLE_vertex_array_object;
- GLboolean APPLE_object_purgeable;
- GLboolean ATI_envmap_bumpmap;
- GLboolean ATI_texture_mirror_once;
- GLboolean ATI_texture_env_combine3;
- GLboolean ATI_fragment_shader;
- GLboolean ATI_separate_stencil;
- GLboolean IBM_rasterpos_clip;
- GLboolean IBM_multimode_draw_arrays;
- GLboolean MESA_pack_invert;
- GLboolean MESA_resize_buffers;
- GLboolean MESA_ycbcr_texture;
- GLboolean MESA_texture_array;
- GLboolean MESA_texture_signed_rgba;
- GLboolean NV_blend_square;
- GLboolean NV_conditional_render;
- GLboolean NV_fragment_program;
- GLboolean NV_fragment_program_option;
- GLboolean NV_light_max_exponent;
- GLboolean NV_point_sprite;
- GLboolean NV_primitive_restart;
- GLboolean NV_texgen_reflection;
- GLboolean NV_texture_env_combine4;
- GLboolean NV_texture_rectangle;
- GLboolean NV_vertex_program;
- GLboolean NV_vertex_program1_1;
- GLboolean OES_read_format;
- GLboolean SGI_texture_color_table;
- GLboolean SGIS_generate_mipmap;
- GLboolean SGIS_texture_edge_clamp;
- GLboolean SGIS_texture_lod;
- GLboolean TDFX_texture_compression_FXT1;
- GLboolean S3_s3tc;
- GLboolean OES_EGL_image;
- GLboolean OES_draw_texture;
- GLboolean EXT_texture_format_BGRA8888;
- GLboolean extension_sentinel;
- /** The extension string */
- const GLubyte *String;
- /** Number of supported extensions */
- GLuint Count;
-};
-
-
-/**
- * A stack of matrices (projection, modelview, color, texture, etc).
- */
-struct gl_matrix_stack
-{
- GLmatrix *Top; /**< points into Stack */
- GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */
- GLuint Depth; /**< 0 <= Depth < MaxDepth */
- GLuint MaxDepth; /**< size of Stack[] array */
- GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */
-};
-
-
-/**
- * \name Bits for image transfer operations
- * \sa __struct gl_contextRec::ImageTransferState.
- */
-/*@{*/
-#define IMAGE_SCALE_BIAS_BIT 0x1
-#define IMAGE_SHIFT_OFFSET_BIT 0x2
-#define IMAGE_MAP_COLOR_BIT 0x4
-#define IMAGE_CLAMP_BIT 0x800
-
-
-/** Pixel Transfer ops */
-#define IMAGE_BITS (IMAGE_SCALE_BIAS_BIT | \
- IMAGE_SHIFT_OFFSET_BIT | \
- IMAGE_MAP_COLOR_BIT)
-
-/**
- * \name Bits to indicate what state has changed.
- *
- * 4 unused flags.
- */
-/*@{*/
-#define _NEW_MODELVIEW 0x1 /**< __struct gl_contextRec::ModelView */
-#define _NEW_PROJECTION 0x2 /**< __struct gl_contextRec::Projection */
-#define _NEW_TEXTURE_MATRIX 0x4 /**< __struct gl_contextRec::TextureMatrix */
-#define _NEW_ACCUM 0x10 /**< __struct gl_contextRec::Accum */
-#define _NEW_COLOR 0x20 /**< __struct gl_contextRec::Color */
-#define _NEW_DEPTH 0x40 /**< __struct gl_contextRec::Depth */
-#define _NEW_EVAL 0x80 /**< __struct gl_contextRec::Eval, __struct gl_contextRec::EvalMap */
-#define _NEW_FOG 0x100 /**< __struct gl_contextRec::Fog */
-#define _NEW_HINT 0x200 /**< __struct gl_contextRec::Hint */
-#define _NEW_LIGHT 0x400 /**< __struct gl_contextRec::Light */
-#define _NEW_LINE 0x800 /**< __struct gl_contextRec::Line */
-#define _NEW_PIXEL 0x1000 /**< __struct gl_contextRec::Pixel */
-#define _NEW_POINT 0x2000 /**< __struct gl_contextRec::Point */
-#define _NEW_POLYGON 0x4000 /**< __struct gl_contextRec::Polygon */
-#define _NEW_POLYGONSTIPPLE 0x8000 /**< __struct gl_contextRec::PolygonStipple */
-#define _NEW_SCISSOR 0x10000 /**< __struct gl_contextRec::Scissor */
-#define _NEW_STENCIL 0x20000 /**< __struct gl_contextRec::Stencil */
-#define _NEW_TEXTURE 0x40000 /**< __struct gl_contextRec::Texture */
-#define _NEW_TRANSFORM 0x80000 /**< __struct gl_contextRec::Transform */
-#define _NEW_VIEWPORT 0x100000 /**< __struct gl_contextRec::Viewport */
-#define _NEW_PACKUNPACK 0x200000 /**< __struct gl_contextRec::Pack, __struct gl_contextRec::Unpack */
-#define _NEW_ARRAY 0x400000 /**< __struct gl_contextRec::Array */
-#define _NEW_RENDERMODE 0x800000 /**< __struct gl_contextRec::RenderMode, __struct gl_contextRec::Feedback, __struct gl_contextRec::Select */
-#define _NEW_BUFFERS 0x1000000 /**< __struct gl_contextRec::Visual, __struct gl_contextRec::DrawBuffer, */
-#define _NEW_MULTISAMPLE 0x2000000 /**< __struct gl_contextRec::Multisample */
-#define _NEW_TRACK_MATRIX 0x4000000 /**< __struct gl_contextRec::VertexProgram */
-#define _NEW_PROGRAM 0x8000000 /**< __struct gl_contextRec::VertexProgram */
-#define _NEW_CURRENT_ATTRIB 0x10000000 /**< __struct gl_contextRec::Current */
-#define _NEW_PROGRAM_CONSTANTS 0x20000000
-#define _NEW_BUFFER_OBJECT 0x40000000
-#define _NEW_ALL ~0
-/*@}*/
-
-
-/**
- * \name Bits to track array state changes
- *
- * Also used to summarize array enabled.
- */
-/*@{*/
-#define _NEW_ARRAY_VERTEX VERT_BIT_POS
-#define _NEW_ARRAY_WEIGHT VERT_BIT_WEIGHT
-#define _NEW_ARRAY_NORMAL VERT_BIT_NORMAL
-#define _NEW_ARRAY_COLOR0 VERT_BIT_COLOR0
-#define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1
-#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG
-#define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX
-#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG
-#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */
-#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0
-#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1
-#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2
-#define _NEW_ARRAY_TEXCOORD_3 VERT_BIT_TEX3
-#define _NEW_ARRAY_TEXCOORD_4 VERT_BIT_TEX4
-#define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5
-#define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6
-#define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7
-#define _NEW_ARRAY_ATTRIB_0 VERT_BIT_GENERIC0 /* start at bit 16 */
-#define _NEW_ARRAY_ALL 0xffffffff
-
-
-#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i))
-#define _NEW_ARRAY_ATTRIB(i) (_NEW_ARRAY_ATTRIB_0 << (i))
-/*@}*/
-
-
-
-/**
- * \name A bunch of flags that we think might be useful to drivers.
- *
- * Set in the __struct gl_contextRec::_TriangleCaps bitfield.
- */
-/*@{*/
-#define DD_FLATSHADE 0x1
-#define DD_SEPARATE_SPECULAR 0x2
-#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */
-#define DD_TRI_LIGHT_TWOSIDE 0x8
-#define DD_TRI_UNFILLED 0x10
-#define DD_TRI_SMOOTH 0x20
-#define DD_TRI_STIPPLE 0x40
-#define DD_TRI_OFFSET 0x80
-#define DD_LINE_SMOOTH 0x100
-#define DD_LINE_STIPPLE 0x200
-#define DD_POINT_SMOOTH 0x400
-#define DD_POINT_ATTEN 0x800
-#define DD_TRI_TWOSTENCIL 0x1000
-/*@}*/
-
-
-/**
- * \name Define the state changes under which each of these bits might change
- */
-/*@{*/
-#define _DD_NEW_FLATSHADE _NEW_LIGHT
-#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG | _NEW_PROGRAM)
-#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON
-#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT
-#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON
-#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON
-#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON
-#define _DD_NEW_TRI_OFFSET _NEW_POLYGON
-#define _DD_NEW_LINE_SMOOTH _NEW_LINE
-#define _DD_NEW_LINE_STIPPLE _NEW_LINE
-#define _DD_NEW_LINE_WIDTH _NEW_LINE
-#define _DD_NEW_POINT_SMOOTH _NEW_POINT
-#define _DD_NEW_POINT_SIZE _NEW_POINT
-#define _DD_NEW_POINT_ATTEN _NEW_POINT
-/*@}*/
-
-
-/**
- * Composite state flags
- */
-/*@{*/
-#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \
- _NEW_TEXTURE | \
- _NEW_POINT | \
- _NEW_PROGRAM | \
- _NEW_MODELVIEW)
-
-#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \
- _NEW_TEXTURE)
-
-#define _MESA_NEW_TRANSFER_STATE (_NEW_PIXEL)
-/*@}*/
-
-
-
-
-/* This has to be included here. */
-#include "dd.h"
-
-
-/**
- * Display list flags.
- * Strictly this is a tnl-private concept, but it doesn't seem
- * worthwhile adding a tnl private structure just to hold this one bit
- * of information:
- */
-#define DLIST_DANGLING_REFS 0x1
-
-
-/** Opaque declaration of display list payload data type */
-union gl_dlist_node;
-
-
-/**
- * Provide a location where information about a display list can be
- * collected. Could be extended with driverPrivate structures,
- * etc. in the future.
- */
-struct gl_display_list
-{
- GLuint Name;
- GLbitfield Flags; /**< DLIST_x flags */
- /** The dlist commands are in a linked list of nodes */
- union gl_dlist_node *Head;
-};
-
-
-/**
- * State used during display list compilation and execution.
- */
-struct gl_dlist_state
-{
- GLuint CallDepth; /**< Current recursion calling depth */
-
- struct gl_display_list *CurrentList; /**< List currently being compiled */
- union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */
- GLuint CurrentPos; /**< Index into current block of nodes */
-
- GLvertexformat ListVtxfmt;
-
- GLubyte ActiveAttribSize[VERT_ATTRIB_MAX];
- GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4];
-
- GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX];
- GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4];
-
- GLubyte ActiveIndex;
- GLfloat CurrentIndex;
-
- GLubyte ActiveEdgeFlag;
- GLboolean CurrentEdgeFlag;
-
- struct {
- /* State known to have been set by the currently-compiling display
- * list. Used to eliminate some redundant state changes.
- */
- GLenum ShadeModel;
- } Current;
-};
-
-/**
- * Enum for the OpenGL APIs we know about and may support.
- */
-typedef enum {
- API_OPENGL,
- API_OPENGLES,
- API_OPENGLES2
-} gl_api;
-
-/**
- * Mesa rendering context.
- *
- * This is the central context data structure for Mesa. Almost all
- * OpenGL state is contained in this structure.
- * Think of this as a base class from which device drivers will derive
- * sub classes.
- *
- * The struct gl_context typedef names this structure.
- */
-struct gl_context
-{
- /** State possibly shared with other contexts in the address space */
- struct gl_shared_state *Shared;
-
- /** \name API function pointer tables */
- /*@{*/
- gl_api API;
- struct _glapi_table *Save; /**< Display list save functions */
- struct _glapi_table *Exec; /**< Execute functions */
- struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */
- /*@}*/
-
- struct gl_config Visual;
- struct gl_framebuffer *DrawBuffer; /**< buffer for writing */
- struct gl_framebuffer *ReadBuffer; /**< buffer for reading */
- struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */
- struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */
-
- /**
- * Device driver function pointer table
- */
- struct dd_function_table Driver;
-
- void *DriverCtx; /**< Points to device driver context/state */
-
- /** Core/Driver constants */
- struct gl_constants Const;
-
- /** \name The various 4x4 matrix stacks */
- /*@{*/
- struct gl_matrix_stack ModelviewMatrixStack;
- struct gl_matrix_stack ProjectionMatrixStack;
- struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS];
- struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
- struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
- /*@}*/
-
- /** Combined modelview and projection matrix */
- GLmatrix _ModelProjectMatrix;
-
- /** \name Display lists */
- struct gl_dlist_state ListState;
-
- GLboolean ExecuteFlag; /**< Execute GL commands? */
- GLboolean CompileFlag; /**< Compile GL commands into display list? */
-
- /** Extension information */
- struct gl_extensions Extensions;
-
- /** Version info */
- GLuint VersionMajor, VersionMinor;
- char *VersionString;
-
- /** \name State attribute stack (for glPush/PopAttrib) */
- /*@{*/
- GLuint AttribStackDepth;
- struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH];
- /*@}*/
-
- /** \name Renderer attribute groups
- *
- * We define a struct for each attribute group to make pushing and popping
- * attributes easy. Also it's a good organization.
- */
- /*@{*/
- struct gl_accum_attrib Accum; /**< Accum buffer attributes */
- struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */
- struct gl_current_attrib Current; /**< Current attributes */
- struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */
- struct gl_eval_attrib Eval; /**< Eval attributes */
- struct gl_fog_attrib Fog; /**< Fog attributes */
- struct gl_hint_attrib Hint; /**< Hint attributes */
- struct gl_light_attrib Light; /**< Light attributes */
- struct gl_line_attrib Line; /**< Line attributes */
- struct gl_list_attrib List; /**< List attributes */
- struct gl_multisample_attrib Multisample;
- struct gl_pixel_attrib Pixel; /**< Pixel attributes */
- struct gl_point_attrib Point; /**< Point attributes */
- struct gl_polygon_attrib Polygon; /**< Polygon attributes */
- GLuint PolygonStipple[32]; /**< Polygon stipple */
- struct gl_scissor_attrib Scissor; /**< Scissor attributes */
- struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */
- struct gl_texture_attrib Texture; /**< Texture attributes */
- struct gl_transform_attrib Transform; /**< Transformation attributes */
- struct gl_viewport_attrib Viewport; /**< Viewport attributes */
- /*@}*/
-
- /** \name Client attribute stack */
- /*@{*/
- GLuint ClientAttribStackDepth;
- struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH];
- /*@}*/
-
- /** \name Client attribute groups */
- /*@{*/
- struct gl_array_attrib Array; /**< Vertex arrays */
- struct gl_pixelstore_attrib Pack; /**< Pixel packing */
- struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */
- struct gl_pixelstore_attrib DefaultPacking; /**< Default params */
- /*@}*/
-
- /** \name Other assorted state (not pushed/popped on attribute stack) */
- /*@{*/
- struct gl_pixelmaps PixelMaps;
-
- struct gl_evaluators EvalMap; /**< All evaluators */
- struct gl_feedback Feedback; /**< Feedback */
- struct gl_selection Select; /**< Selection */
-
- struct gl_program_state Program; /**< general program state */
- struct gl_vertex_program_state VertexProgram;
- struct gl_fragment_program_state FragmentProgram;
- struct gl_geometry_program_state GeometryProgram;
- struct gl_ati_fragment_shader_state ATIFragmentShader;
-
- struct gl_shader_state Shader; /**< GLSL shader object state */
- struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES];
-
- struct gl_query_state Query; /**< occlusion, timer queries */
-
- struct gl_transform_feedback TransformFeedback;
-
- struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */
- struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
- /*@}*/
-
- struct gl_meta_state *Meta; /**< for "meta" operations */
-
- /* GL_EXT_framebuffer_object */
- struct gl_renderbuffer *CurrentRenderbuffer;
-
- GLenum ErrorValue; /**< Last error code */
-
- /**
- * Recognize and silence repeated error debug messages in buggy apps.
- */
- const char *ErrorDebugFmtString;
- GLuint ErrorDebugCount;
-
- GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
- GLbitfield NewState; /**< bitwise-or of _NEW_* flags */
-
- GLboolean ViewportInitialized; /**< has viewport size been initialized? */
-
- GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */
-
- /** \name Derived state */
- /*@{*/
- /** Bitwise-or of DD_* flags. Note that this bitfield may be used before
- * state validation so they need to always be current.
- */
- GLbitfield _TriangleCaps;
- GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */
- GLfloat _EyeZDir[3];
- GLfloat _ModelViewInvScale;
- GLboolean _NeedEyeCoords;
- GLboolean _ForceEyeCoords;
-
- GLuint TextureStateTimestamp; /**< detect changes to shared state */
-
- struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */
- struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */
- /**@}*/
-
- struct gl_list_extensions *ListExt; /**< driver dlist extensions */
-
- /** \name For debugging/development only */
- /*@{*/
- GLboolean FirstTimeCurrent;
- /*@}*/
-
- /** Dither disable via MESA_NO_DITHER env var */
- GLboolean NoDither;
-
- /** software compression/decompression supported or not */
- GLboolean Mesa_DXTn;
-
- GLboolean TextureFormatSupported[MESA_FORMAT_COUNT];
-
- /**
- * Use dp4 (rather than mul/mad) instructions for position
- * transformation?
- */
- GLboolean mvp_with_dp4;
-
- /**
- * \name Hooks for module contexts.
- *
- * These will eventually live in the driver or elsewhere.
- */
- /*@{*/
- void *swrast_context;
- void *swsetup_context;
- void *swtnl_context;
- void *swtnl_im;
- struct st_context *st;
- void *aelt_context;
- /*@}*/
-};
-
-
-/** The string names for GL_POINT, GL_LINE_LOOP, etc */
-extern const char *_mesa_prim_name[GL_POLYGON+4];
-
-
-#ifdef DEBUG
-extern int MESA_VERBOSE;
-extern int MESA_DEBUG_FLAGS;
-# define MESA_FUNCTION __FUNCTION__
-#else
-# define MESA_VERBOSE 0
-# define MESA_DEBUG_FLAGS 0
-# define MESA_FUNCTION "a function"
-# ifndef NDEBUG
-# define NDEBUG
-# endif
-#endif
-
-
-/** The MESA_VERBOSE var is a bitmask of these flags */
-enum _verbose
-{
- VERBOSE_VARRAY = 0x0001,
- VERBOSE_TEXTURE = 0x0002,
- VERBOSE_MATERIAL = 0x0004,
- VERBOSE_PIPELINE = 0x0008,
- VERBOSE_DRIVER = 0x0010,
- VERBOSE_STATE = 0x0020,
- VERBOSE_API = 0x0040,
- VERBOSE_DISPLAY_LIST = 0x0100,
- VERBOSE_LIGHTING = 0x0200,
- VERBOSE_PRIMS = 0x0400,
- VERBOSE_VERTS = 0x0800,
- VERBOSE_DISASSEM = 0x1000,
- VERBOSE_DRAW = 0x2000,
- VERBOSE_SWAPBUFFERS = 0x4000
-};
-
-
-/** The MESA_DEBUG_FLAGS var is a bitmask of these flags */
-enum _debug
-{
- DEBUG_ALWAYS_FLUSH = 0x1
-};
-
-
-
-#endif /* MTYPES_H */
+/* + * Mesa 3-D graphics library + * Version: 7.7 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file mtypes.h + * Main Mesa data structures. + * + * Please try to mark derived values with a leading underscore ('_'). + */ + +#ifndef MTYPES_H +#define MTYPES_H + + +#include "main/glheader.h" +#include "main/config.h" +#include "main/mfeatures.h" +#include "glapi/glapi.h" +#include "math/m_matrix.h" /* GLmatrix */ +#include "main/simple_list.h" /* struct simple_node */ +#include "main/formats.h" /* MESA_FORMAT_COUNT */ + + +/** + * Color channel data type. + */ +#if CHAN_BITS == 8 + typedef GLubyte GLchan; +#define CHAN_MAX 255 +#define CHAN_MAXF 255.0F +#define CHAN_TYPE GL_UNSIGNED_BYTE +#elif CHAN_BITS == 16 + typedef GLushort GLchan; +#define CHAN_MAX 65535 +#define CHAN_MAXF 65535.0F +#define CHAN_TYPE GL_UNSIGNED_SHORT +#elif CHAN_BITS == 32 + typedef GLfloat GLchan; +#define CHAN_MAX 1.0 +#define CHAN_MAXF 1.0F +#define CHAN_TYPE GL_FLOAT +#else +#error "illegal number of color channel bits" +#endif + + +/** + * Stencil buffer data type. + */ +#if STENCIL_BITS==8 + typedef GLubyte GLstencil; +#elif STENCIL_BITS==16 + typedef GLushort GLstencil; +#else +# error "illegal number of stencil bits" +#endif + + +/** + * \name 64-bit extension of GLbitfield. + */ +/*@{*/ +typedef GLuint64 GLbitfield64; + +#define BITFIELD64_ONE 1ULL +#define BITFIELD64_ALLONES ~0ULL + +/** Set a single bit */ +#define BITFIELD64_BIT(b) (BITFIELD64_ONE << (b)) + +/** Set a mask of the least significant \c b bits */ +#define BITFIELD64_MASK(b) (((b) >= 64) ? BITFIELD64_ALLONES : \ + (BITFIELD64_BIT(b) - 1)) + +/** + * Set all bits from l (low bit) to h (high bit), inclusive. + * + * \note \C BITFIELD_64_RANGE(0, 63) return 64 set bits. + */ +#define BITFIELD64_RANGE(l, h) (BITFIELD64_MASK((h) + 1) & ~BITFIELD64_MASK(l)) +/*@}*/ + + +/** + * \name Some forward type declarations + */ +/*@{*/ +struct _mesa_HashTable; +struct gl_attrib_node; +struct gl_list_extensions; +struct gl_meta_state; +struct gl_pixelstore_attrib; +struct gl_program_cache; +struct gl_texture_format; +struct gl_texture_image; +struct gl_texture_object; +struct gl_context; +struct st_context; +/*@}*/ + + + +/** + * Shader stages. Note that these will become 5 with tessellation. + * These MUST have the same values as gallium's PIPE_SHADER_* + */ +typedef enum +{ + MESA_SHADER_VERTEX = 0, + MESA_SHADER_FRAGMENT = 1, + MESA_SHADER_GEOMETRY = 2, + MESA_SHADER_TYPES = 3 +} gl_shader_type; + + + +/** + * Indexes for vertex program attributes. + * GL_NV_vertex_program aliases generic attributes over the conventional + * attributes. In GL_ARB_vertex_program shader the aliasing is optional. + * In GL_ARB_vertex_shader / OpenGL 2.0 the aliasing is disallowed (the + * generic attributes are distinct/separate). + */ +typedef enum +{ + VERT_ATTRIB_POS = 0, + VERT_ATTRIB_WEIGHT = 1, + VERT_ATTRIB_NORMAL = 2, + VERT_ATTRIB_COLOR0 = 3, + VERT_ATTRIB_COLOR1 = 4, + VERT_ATTRIB_FOG = 5, + VERT_ATTRIB_COLOR_INDEX = 6, + VERT_ATTRIB_POINT_SIZE = 6, /*alias*/ + VERT_ATTRIB_EDGEFLAG = 7, + VERT_ATTRIB_TEX0 = 8, + VERT_ATTRIB_TEX1 = 9, + VERT_ATTRIB_TEX2 = 10, + VERT_ATTRIB_TEX3 = 11, + VERT_ATTRIB_TEX4 = 12, + VERT_ATTRIB_TEX5 = 13, + VERT_ATTRIB_TEX6 = 14, + VERT_ATTRIB_TEX7 = 15, + VERT_ATTRIB_GENERIC0 = 16, + VERT_ATTRIB_GENERIC1 = 17, + VERT_ATTRIB_GENERIC2 = 18, + VERT_ATTRIB_GENERIC3 = 19, + VERT_ATTRIB_GENERIC4 = 20, + VERT_ATTRIB_GENERIC5 = 21, + VERT_ATTRIB_GENERIC6 = 22, + VERT_ATTRIB_GENERIC7 = 23, + VERT_ATTRIB_GENERIC8 = 24, + VERT_ATTRIB_GENERIC9 = 25, + VERT_ATTRIB_GENERIC10 = 26, + VERT_ATTRIB_GENERIC11 = 27, + VERT_ATTRIB_GENERIC12 = 28, + VERT_ATTRIB_GENERIC13 = 29, + VERT_ATTRIB_GENERIC14 = 30, + VERT_ATTRIB_GENERIC15 = 31, + VERT_ATTRIB_MAX = 32 +} gl_vert_attrib; + +/** + * Bitflags for vertex attributes. + * These are used in bitfields in many places. + */ +/*@{*/ +#define VERT_BIT_POS (1 << VERT_ATTRIB_POS) +#define VERT_BIT_WEIGHT (1 << VERT_ATTRIB_WEIGHT) +#define VERT_BIT_NORMAL (1 << VERT_ATTRIB_NORMAL) +#define VERT_BIT_COLOR0 (1 << VERT_ATTRIB_COLOR0) +#define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1) +#define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG) +#define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX) +#define VERT_BIT_EDGEFLAG (1 << VERT_ATTRIB_EDGEFLAG) +#define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0) +#define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1) +#define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2) +#define VERT_BIT_TEX3 (1 << VERT_ATTRIB_TEX3) +#define VERT_BIT_TEX4 (1 << VERT_ATTRIB_TEX4) +#define VERT_BIT_TEX5 (1 << VERT_ATTRIB_TEX5) +#define VERT_BIT_TEX6 (1 << VERT_ATTRIB_TEX6) +#define VERT_BIT_TEX7 (1 << VERT_ATTRIB_TEX7) +#define VERT_BIT_GENERIC0 (1 << VERT_ATTRIB_GENERIC0) +#define VERT_BIT_GENERIC1 (1 << VERT_ATTRIB_GENERIC1) +#define VERT_BIT_GENERIC2 (1 << VERT_ATTRIB_GENERIC2) +#define VERT_BIT_GENERIC3 (1 << VERT_ATTRIB_GENERIC3) +#define VERT_BIT_GENERIC4 (1 << VERT_ATTRIB_GENERIC4) +#define VERT_BIT_GENERIC5 (1 << VERT_ATTRIB_GENERIC5) +#define VERT_BIT_GENERIC6 (1 << VERT_ATTRIB_GENERIC6) +#define VERT_BIT_GENERIC7 (1 << VERT_ATTRIB_GENERIC7) +#define VERT_BIT_GENERIC8 (1 << VERT_ATTRIB_GENERIC8) +#define VERT_BIT_GENERIC9 (1 << VERT_ATTRIB_GENERIC9) +#define VERT_BIT_GENERIC10 (1 << VERT_ATTRIB_GENERIC10) +#define VERT_BIT_GENERIC11 (1 << VERT_ATTRIB_GENERIC11) +#define VERT_BIT_GENERIC12 (1 << VERT_ATTRIB_GENERIC12) +#define VERT_BIT_GENERIC13 (1 << VERT_ATTRIB_GENERIC13) +#define VERT_BIT_GENERIC14 (1 << VERT_ATTRIB_GENERIC14) +#define VERT_BIT_GENERIC15 (1 << VERT_ATTRIB_GENERIC15) + +#define VERT_BIT_TEX(u) (1 << (VERT_ATTRIB_TEX0 + (u))) +#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g))) +/*@}*/ + + +/** + * Indexes for vertex program result attributes + */ +typedef enum +{ + VERT_RESULT_HPOS = 0, + VERT_RESULT_COL0 = 1, + VERT_RESULT_COL1 = 2, + VERT_RESULT_FOGC = 3, + VERT_RESULT_TEX0 = 4, + VERT_RESULT_TEX1 = 5, + VERT_RESULT_TEX2 = 6, + VERT_RESULT_TEX3 = 7, + VERT_RESULT_TEX4 = 8, + VERT_RESULT_TEX5 = 9, + VERT_RESULT_TEX6 = 10, + VERT_RESULT_TEX7 = 11, + VERT_RESULT_PSIZ = 12, + VERT_RESULT_BFC0 = 13, + VERT_RESULT_BFC1 = 14, + VERT_RESULT_EDGE = 15, + VERT_RESULT_VAR0 = 16, /**< shader varying */ + VERT_RESULT_MAX = (VERT_RESULT_VAR0 + MAX_VARYING) +} gl_vert_result; + + +/*********************************************/ + +/** + * Indexes for geometry program attributes. + */ +typedef enum +{ + GEOM_ATTRIB_POSITION = 0, + GEOM_ATTRIB_COLOR0 = 1, + GEOM_ATTRIB_COLOR1 = 2, + GEOM_ATTRIB_SECONDARY_COLOR0 = 3, + GEOM_ATTRIB_SECONDARY_COLOR1 = 4, + GEOM_ATTRIB_FOG_FRAG_COORD = 5, + GEOM_ATTRIB_POINT_SIZE = 6, + GEOM_ATTRIB_CLIP_VERTEX = 7, + GEOM_ATTRIB_PRIMITIVE_ID = 8, + GEOM_ATTRIB_TEX_COORD = 9, + + GEOM_ATTRIB_VAR0 = 16, + GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING) +} gl_geom_attrib; + +/** + * Bitflags for geometry attributes. + * These are used in bitfields in many places. + */ +/*@{*/ +#define GEOM_BIT_COLOR0 (1 << GEOM_ATTRIB_COLOR0) +#define GEOM_BIT_COLOR1 (1 << GEOM_ATTRIB_COLOR1) +#define GEOM_BIT_SCOLOR0 (1 << GEOM_ATTRIB_SECONDARY_COLOR0) +#define GEOM_BIT_SCOLOR1 (1 << GEOM_ATTRIB_SECONDARY_COLOR1) +#define GEOM_BIT_TEX_COORD (1 << GEOM_ATTRIB_TEX_COORD) +#define GEOM_BIT_FOG_COORD (1 << GEOM_ATTRIB_FOG_FRAG_COORD) +#define GEOM_BIT_POSITION (1 << GEOM_ATTRIB_POSITION) +#define GEOM_BIT_POINT_SIDE (1 << GEOM_ATTRIB_POINT_SIZE) +#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX) +#define GEOM_BIT_PRIM_ID (1 << GEOM_ATTRIB_PRIMITIVE_ID) +#define GEOM_BIT_VAR0 (1 << GEOM_ATTRIB_VAR0) + +#define GEOM_BIT_VAR(g) (1 << (GEOM_BIT_VAR0 + (g))) +/*@}*/ + + +/** + * Indexes for geometry program result attributes + */ +/*@{*/ +typedef enum { + GEOM_RESULT_POS = 0, + GEOM_RESULT_COL0 = 1, + GEOM_RESULT_COL1 = 2, + GEOM_RESULT_SCOL0 = 3, + GEOM_RESULT_SCOL1 = 4, + GEOM_RESULT_FOGC = 5, + GEOM_RESULT_TEX0 = 6, + GEOM_RESULT_TEX1 = 7, + GEOM_RESULT_TEX2 = 8, + GEOM_RESULT_TEX3 = 9, + GEOM_RESULT_TEX4 = 10, + GEOM_RESULT_TEX5 = 11, + GEOM_RESULT_TEX6 = 12, + GEOM_RESULT_TEX7 = 13, + GEOM_RESULT_PSIZ = 14, + GEOM_RESULT_CLPV = 15, + GEOM_RESULT_PRID = 16, + GEOM_RESULT_LAYR = 17, + GEOM_RESULT_VAR0 = 18, /**< shader varying, should really be 16 */ + /* ### we need to -2 because var0 is 18 instead 16 like in the others */ + GEOM_RESULT_MAX = (GEOM_RESULT_VAR0 + MAX_VARYING - 2) +} gl_geom_result; +/*@}*/ + +/** + * Indexes for fragment program input attributes. + */ +typedef enum +{ + FRAG_ATTRIB_WPOS = 0, + FRAG_ATTRIB_COL0 = 1, + FRAG_ATTRIB_COL1 = 2, + FRAG_ATTRIB_FOGC = 3, + FRAG_ATTRIB_TEX0 = 4, + FRAG_ATTRIB_TEX1 = 5, + FRAG_ATTRIB_TEX2 = 6, + FRAG_ATTRIB_TEX3 = 7, + FRAG_ATTRIB_TEX4 = 8, + FRAG_ATTRIB_TEX5 = 9, + FRAG_ATTRIB_TEX6 = 10, + FRAG_ATTRIB_TEX7 = 11, + FRAG_ATTRIB_FACE = 12, /**< front/back face */ + FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */ + FRAG_ATTRIB_VAR0 = 14, /**< shader varying */ + FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING) +} gl_frag_attrib; + +/** + * Bitflags for fragment program input attributes. + */ +/*@{*/ +#define FRAG_BIT_WPOS (1 << FRAG_ATTRIB_WPOS) +#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0) +#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1) +#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC) +#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE) +#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC) +#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0) +#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1) +#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2) +#define FRAG_BIT_TEX3 (1 << FRAG_ATTRIB_TEX3) +#define FRAG_BIT_TEX4 (1 << FRAG_ATTRIB_TEX4) +#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5) +#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6) +#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7) +#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0) + +#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U)) +#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V)) + +#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \ + FRAG_BIT_TEX1| \ + FRAG_BIT_TEX2| \ + FRAG_BIT_TEX3| \ + FRAG_BIT_TEX4| \ + FRAG_BIT_TEX5| \ + FRAG_BIT_TEX6| \ + FRAG_BIT_TEX7) +/*@}*/ + + +/** + * Fragment program results + */ +typedef enum +{ + FRAG_RESULT_DEPTH = 0, + FRAG_RESULT_STENCIL = 1, + FRAG_RESULT_COLOR = 2, + FRAG_RESULT_DATA0 = 3, + FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS) +} gl_frag_result; + + +/** + * Indexes for all renderbuffers + */ +typedef enum +{ + /* the four standard color buffers */ + BUFFER_FRONT_LEFT, + BUFFER_BACK_LEFT, + BUFFER_FRONT_RIGHT, + BUFFER_BACK_RIGHT, + BUFFER_DEPTH, + BUFFER_STENCIL, + BUFFER_ACCUM, + /* optional aux buffer */ + BUFFER_AUX0, + /* generic renderbuffers */ + BUFFER_COLOR0, + BUFFER_COLOR1, + BUFFER_COLOR2, + BUFFER_COLOR3, + BUFFER_COLOR4, + BUFFER_COLOR5, + BUFFER_COLOR6, + BUFFER_COLOR7, + BUFFER_COUNT +} gl_buffer_index; + +/** + * Bit flags for all renderbuffers + */ +#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT) +#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT) +#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT) +#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT) +#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0) +#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1) +#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2) +#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3) +#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH) +#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL) +#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM) +#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0) +#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1) +#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2) +#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3) +#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4) +#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5) +#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6) +#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7) + +/** + * Mask of all the color buffer bits (but not accum). + */ +#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \ + BUFFER_BIT_BACK_LEFT | \ + BUFFER_BIT_FRONT_RIGHT | \ + BUFFER_BIT_BACK_RIGHT | \ + BUFFER_BIT_AUX0 | \ + BUFFER_BIT_COLOR0 | \ + BUFFER_BIT_COLOR1 | \ + BUFFER_BIT_COLOR2 | \ + BUFFER_BIT_COLOR3 | \ + BUFFER_BIT_COLOR4 | \ + BUFFER_BIT_COLOR5 | \ + BUFFER_BIT_COLOR6 | \ + BUFFER_BIT_COLOR7) + + +/** + * Framebuffer configuration (aka visual / pixelformat) + * Note: some of these fields should be boolean, but it appears that + * code in drivers/dri/common/util.c requires int-sized fields. + */ +struct gl_config +{ + GLboolean rgbMode; + GLboolean floatMode; + GLboolean colorIndexMode; /* XXX is this used anywhere? */ + GLuint doubleBufferMode; + GLuint stereoMode; + + GLboolean haveAccumBuffer; + GLboolean haveDepthBuffer; + GLboolean haveStencilBuffer; + + GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ + GLuint redMask, greenMask, blueMask, alphaMask; + GLint rgbBits; /* total bits for rgb */ + GLint indexBits; /* total bits for colorindex */ + + GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; + GLint depthBits; + GLint stencilBits; + + GLint numAuxBuffers; + + GLint level; + + /* EXT_visual_rating / GLX 1.2 */ + GLint visualRating; + + /* EXT_visual_info / GLX 1.2 */ + GLint transparentPixel; + /* colors are floats scaled to ints */ + GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; + GLint transparentIndex; + + /* ARB_multisample / SGIS_multisample */ + GLint sampleBuffers; + GLint samples; + + /* SGIX_pbuffer / GLX 1.3 */ + GLint maxPbufferWidth; + GLint maxPbufferHeight; + GLint maxPbufferPixels; + GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ + GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ + + /* OML_swap_method */ + GLint swapMethod; + + /* EXT_texture_from_pixmap */ + GLint bindToTextureRgb; + GLint bindToTextureRgba; + GLint bindToMipmapTexture; + GLint bindToTextureTargets; + GLint yInverted; +}; + + +/** + * Data structure for color tables + */ +struct gl_color_table +{ + GLenum InternalFormat; /**< The user-specified format */ + GLenum _BaseFormat; /**< GL_ALPHA, GL_RGBA, GL_RGB, etc */ + GLuint Size; /**< number of entries in table */ + GLfloat *TableF; /**< Color table, floating point values */ + GLubyte *TableUB; /**< Color table, ubyte values */ + GLubyte RedSize; + GLubyte GreenSize; + GLubyte BlueSize; + GLubyte AlphaSize; + GLubyte LuminanceSize; + GLubyte IntensitySize; +}; + + +/** + * \name Bit flags used for updating material values. + */ +/*@{*/ +#define MAT_ATTRIB_FRONT_AMBIENT 0 +#define MAT_ATTRIB_BACK_AMBIENT 1 +#define MAT_ATTRIB_FRONT_DIFFUSE 2 +#define MAT_ATTRIB_BACK_DIFFUSE 3 +#define MAT_ATTRIB_FRONT_SPECULAR 4 +#define MAT_ATTRIB_BACK_SPECULAR 5 +#define MAT_ATTRIB_FRONT_EMISSION 6 +#define MAT_ATTRIB_BACK_EMISSION 7 +#define MAT_ATTRIB_FRONT_SHININESS 8 +#define MAT_ATTRIB_BACK_SHININESS 9 +#define MAT_ATTRIB_FRONT_INDEXES 10 +#define MAT_ATTRIB_BACK_INDEXES 11 +#define MAT_ATTRIB_MAX 12 + +#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f)) +#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f)) +#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f)) +#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f)) +#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f)) +#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f)) + +#define MAT_INDEX_AMBIENT 0 +#define MAT_INDEX_DIFFUSE 1 +#define MAT_INDEX_SPECULAR 2 + +#define MAT_BIT_FRONT_AMBIENT (1<<MAT_ATTRIB_FRONT_AMBIENT) +#define MAT_BIT_BACK_AMBIENT (1<<MAT_ATTRIB_BACK_AMBIENT) +#define MAT_BIT_FRONT_DIFFUSE (1<<MAT_ATTRIB_FRONT_DIFFUSE) +#define MAT_BIT_BACK_DIFFUSE (1<<MAT_ATTRIB_BACK_DIFFUSE) +#define MAT_BIT_FRONT_SPECULAR (1<<MAT_ATTRIB_FRONT_SPECULAR) +#define MAT_BIT_BACK_SPECULAR (1<<MAT_ATTRIB_BACK_SPECULAR) +#define MAT_BIT_FRONT_EMISSION (1<<MAT_ATTRIB_FRONT_EMISSION) +#define MAT_BIT_BACK_EMISSION (1<<MAT_ATTRIB_BACK_EMISSION) +#define MAT_BIT_FRONT_SHININESS (1<<MAT_ATTRIB_FRONT_SHININESS) +#define MAT_BIT_BACK_SHININESS (1<<MAT_ATTRIB_BACK_SHININESS) +#define MAT_BIT_FRONT_INDEXES (1<<MAT_ATTRIB_FRONT_INDEXES) +#define MAT_BIT_BACK_INDEXES (1<<MAT_ATTRIB_BACK_INDEXES) + + +#define FRONT_MATERIAL_BITS (MAT_BIT_FRONT_EMISSION | \ + MAT_BIT_FRONT_AMBIENT | \ + MAT_BIT_FRONT_DIFFUSE | \ + MAT_BIT_FRONT_SPECULAR | \ + MAT_BIT_FRONT_SHININESS | \ + MAT_BIT_FRONT_INDEXES) + +#define BACK_MATERIAL_BITS (MAT_BIT_BACK_EMISSION | \ + MAT_BIT_BACK_AMBIENT | \ + MAT_BIT_BACK_DIFFUSE | \ + MAT_BIT_BACK_SPECULAR | \ + MAT_BIT_BACK_SHININESS | \ + MAT_BIT_BACK_INDEXES) + +#define ALL_MATERIAL_BITS (FRONT_MATERIAL_BITS | BACK_MATERIAL_BITS) +/*@}*/ + + +#define EXP_TABLE_SIZE 512 /**< Specular exponent lookup table sizes */ +#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */ + +/** + * Material shininess lookup table. + */ +struct gl_shine_tab +{ + struct gl_shine_tab *next, *prev; + GLfloat tab[SHINE_TABLE_SIZE+1]; + GLfloat shininess; + GLuint refcount; +}; + + +/** + * Light source state. + */ +struct gl_light +{ + struct gl_light *next; /**< double linked list with sentinel */ + struct gl_light *prev; + + GLfloat Ambient[4]; /**< ambient color */ + GLfloat Diffuse[4]; /**< diffuse color */ + GLfloat Specular[4]; /**< specular color */ + GLfloat EyePosition[4]; /**< position in eye coordinates */ + GLfloat SpotDirection[4]; /**< spotlight direction in eye coordinates */ + GLfloat SpotExponent; + GLfloat SpotCutoff; /**< in degrees */ + GLfloat _CosCutoffNeg; /**< = cos(SpotCutoff) */ + GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */ + GLfloat ConstantAttenuation; + GLfloat LinearAttenuation; + GLfloat QuadraticAttenuation; + GLboolean Enabled; /**< On/off flag */ + + /** + * \name Derived fields + */ + /*@{*/ + GLbitfield _Flags; /**< State */ + + GLfloat _Position[4]; /**< position in eye/obj coordinates */ + GLfloat _VP_inf_norm[3]; /**< Norm direction to infinite light */ + GLfloat _h_inf_norm[3]; /**< Norm( _VP_inf_norm + <0,0,1> ) */ + GLfloat _NormSpotDirection[4]; /**< normalized spotlight direction */ + GLfloat _VP_inf_spot_attenuation; + + GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /**< to replace a pow() call */ + GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */ + GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */ + GLfloat _MatSpecular[2][3]; /**< material spec * light specular */ + GLfloat _dli; /**< CI diffuse light intensity */ + GLfloat _sli; /**< CI specular light intensity */ + /*@}*/ +}; + + +/** + * Light model state. + */ +struct gl_lightmodel +{ + GLfloat Ambient[4]; /**< ambient color */ + GLboolean LocalViewer; /**< Local (or infinite) view point? */ + GLboolean TwoSide; /**< Two (or one) sided lighting? */ + GLenum ColorControl; /**< either GL_SINGLE_COLOR + * or GL_SEPARATE_SPECULAR_COLOR */ +}; + + +/** + * Material state. + */ +struct gl_material +{ + GLfloat Attrib[MAT_ATTRIB_MAX][4]; +}; + + +/** + * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT) + */ +struct gl_accum_attrib +{ + GLfloat ClearColor[4]; /**< Accumulation buffer clear color */ +}; + + +/** + * Color buffer attribute group (GL_COLOR_BUFFER_BIT). + */ +struct gl_colorbuffer_attrib +{ + GLuint ClearIndex; /**< Index to use for glClear */ + GLclampf ClearColor[4]; /**< Color to use for glClear */ + + GLuint IndexMask; /**< Color index write mask */ + GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */ + + GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */ + + /** + * \name alpha testing + */ + /*@{*/ + GLboolean AlphaEnabled; /**< Alpha test enabled flag */ + GLenum AlphaFunc; /**< Alpha test function */ + GLclampf AlphaRef; /**< Alpha reference value */ + /*@}*/ + + /** + * \name Blending + */ + /*@{*/ + GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */ + GLfloat BlendColor[4]; /**< Blending color */ + struct + { + GLenum SrcRGB; /**< RGB blend source term */ + GLenum DstRGB; /**< RGB blend dest term */ + GLenum SrcA; /**< Alpha blend source term */ + GLenum DstA; /**< Alpha blend dest term */ + GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */ + GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */ + } Blend[MAX_DRAW_BUFFERS]; + /** Are the blend func terms currently different for each buffer/target? */ + GLboolean _BlendFuncPerBuffer; + /** Are the blend equations currently different for each buffer/target? */ + GLboolean _BlendEquationPerBuffer; + /*@}*/ + + /** + * \name Logic op + */ + /*@{*/ + GLenum LogicOp; /**< Logic operator */ + GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */ + GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */ + GLboolean _LogicOpEnabled; /**< RGBA logic op + EXT_blend_logic_op enabled flag */ + /*@}*/ + + GLboolean DitherFlag; /**< Dither enable flag */ + + GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ + GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ +}; + + +/** + * Current attribute group (GL_CURRENT_BIT). + */ +struct gl_current_attrib +{ + /** + * \name Current vertex attributes. + * \note Values are valid only after FLUSH_VERTICES has been called. + * \note Index and Edgeflag current values are stored as floats in the + * SIX and SEVEN attribute slots. + */ + GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */ + + /** + * \name Current raster position attributes (always valid). + * \note This set of attributes is very similar to the SWvertex struct. + */ + /*@{*/ + GLfloat RasterPos[4]; + GLfloat RasterDistance; + GLfloat RasterColor[4]; + GLfloat RasterSecondaryColor[4]; + GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4]; + GLboolean RasterPosValid; + /*@}*/ +}; + + +/** + * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT). + */ +struct gl_depthbuffer_attrib +{ + GLenum Func; /**< Function for depth buffer compare */ + GLclampd Clear; /**< Value to clear depth buffer to */ + GLboolean Test; /**< Depth buffering enabled flag */ + GLboolean Mask; /**< Depth buffer writable? */ + GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */ + GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */ +}; + + +/** + * Evaluator attribute group (GL_EVAL_BIT). + */ +struct gl_eval_attrib +{ + /** + * \name Enable bits + */ + /*@{*/ + GLboolean Map1Color4; + GLboolean Map1Index; + GLboolean Map1Normal; + GLboolean Map1TextureCoord1; + GLboolean Map1TextureCoord2; + GLboolean Map1TextureCoord3; + GLboolean Map1TextureCoord4; + GLboolean Map1Vertex3; + GLboolean Map1Vertex4; + GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */ + GLboolean Map2Color4; + GLboolean Map2Index; + GLboolean Map2Normal; + GLboolean Map2TextureCoord1; + GLboolean Map2TextureCoord2; + GLboolean Map2TextureCoord3; + GLboolean Map2TextureCoord4; + GLboolean Map2Vertex3; + GLboolean Map2Vertex4; + GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */ + GLboolean AutoNormal; + /*@}*/ + + /** + * \name Map Grid endpoints and divisions and calculated du values + */ + /*@{*/ + GLint MapGrid1un; + GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du; + GLint MapGrid2un, MapGrid2vn; + GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du; + GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv; + /*@}*/ +}; + + +/** + * Fog attribute group (GL_FOG_BIT). + */ +struct gl_fog_attrib +{ + GLboolean Enabled; /**< Fog enabled flag */ + GLfloat Color[4]; /**< Fog color */ + GLfloat Density; /**< Density >= 0.0 */ + GLfloat Start; /**< Start distance in eye coords */ + GLfloat End; /**< End distance in eye coords */ + GLfloat Index; /**< Fog index */ + GLenum Mode; /**< Fog mode */ + GLboolean ColorSumEnabled; + GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */ + GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */ +}; + + +/** + * Hint attribute group (GL_HINT_BIT). + * + * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE. + */ +struct gl_hint_attrib +{ + GLenum PerspectiveCorrection; + GLenum PointSmooth; + GLenum LineSmooth; + GLenum PolygonSmooth; + GLenum Fog; + GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */ + GLenum TextureCompression; /**< GL_ARB_texture_compression */ + GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */ + GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */ +}; + +/** + * Light state flags. + */ +/*@{*/ +#define LIGHT_SPOT 0x1 +#define LIGHT_LOCAL_VIEWER 0x2 +#define LIGHT_POSITIONAL 0x4 +#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER) +/*@}*/ + + +/** + * Lighting attribute group (GL_LIGHT_BIT). + */ +struct gl_light_attrib +{ + struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */ + struct gl_lightmodel Model; /**< Lighting model */ + + /** + * Must flush FLUSH_VERTICES before referencing: + */ + /*@{*/ + struct gl_material Material; /**< Includes front & back values */ + /*@}*/ + + GLboolean Enabled; /**< Lighting enabled flag */ + GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */ + GLenum ProvokingVertex; /**< GL_EXT_provoking_vertex */ + GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */ + GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */ + GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */ + GLboolean ColorMaterialEnabled; + GLenum ClampVertexColor; + + struct gl_light EnabledList; /**< List sentinel */ + + /** + * Derived state for optimizations: + */ + /*@{*/ + GLboolean _NeedEyeCoords; + GLboolean _NeedVertices; /**< Use fast shader? */ + GLbitfield _Flags; /**< LIGHT_* flags, see above */ + GLfloat _BaseColor[2][3]; + /*@}*/ +}; + + +/** + * Line attribute group (GL_LINE_BIT). + */ +struct gl_line_attrib +{ + GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */ + GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */ + GLushort StipplePattern; /**< Stipple pattern */ + GLint StippleFactor; /**< Stipple repeat factor */ + GLfloat Width; /**< Line width */ +}; + + +/** + * Display list attribute group (GL_LIST_BIT). + */ +struct gl_list_attrib +{ + GLuint ListBase; +}; + + +/** + * Multisample attribute group (GL_MULTISAMPLE_BIT). + */ +struct gl_multisample_attrib +{ + GLboolean Enabled; + GLboolean _Enabled; /**< true if Enabled and multisample buffer */ + GLboolean SampleAlphaToCoverage; + GLboolean SampleAlphaToOne; + GLboolean SampleCoverage; + GLfloat SampleCoverageValue; + GLboolean SampleCoverageInvert; +}; + + +/** + * A pixelmap (see glPixelMap) + */ +struct gl_pixelmap +{ + GLint Size; + GLfloat Map[MAX_PIXEL_MAP_TABLE]; + GLubyte Map8[MAX_PIXEL_MAP_TABLE]; /**< converted to 8-bit color */ +}; + + +/** + * Collection of all pixelmaps + */ +struct gl_pixelmaps +{ + struct gl_pixelmap RtoR; /**< i.e. GL_PIXEL_MAP_R_TO_R */ + struct gl_pixelmap GtoG; + struct gl_pixelmap BtoB; + struct gl_pixelmap AtoA; + struct gl_pixelmap ItoR; + struct gl_pixelmap ItoG; + struct gl_pixelmap ItoB; + struct gl_pixelmap ItoA; + struct gl_pixelmap ItoI; + struct gl_pixelmap StoS; +}; + + +/** + * Pixel attribute group (GL_PIXEL_MODE_BIT). + */ +struct gl_pixel_attrib +{ + GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */ + + /*--- Begin Pixel Transfer State ---*/ + /* Fields are in the order in which they're applied... */ + + /** Scale & Bias (index shift, offset) */ + /*@{*/ + GLfloat RedBias, RedScale; + GLfloat GreenBias, GreenScale; + GLfloat BlueBias, BlueScale; + GLfloat AlphaBias, AlphaScale; + GLfloat DepthBias, DepthScale; + GLint IndexShift, IndexOffset; + /*@}*/ + + /* Pixel Maps */ + /* Note: actual pixel maps are not part of this attrib group */ + GLboolean MapColorFlag; + GLboolean MapStencilFlag; + + /*--- End Pixel Transfer State ---*/ + + /** glPixelZoom */ + GLfloat ZoomX, ZoomY; + + /** GL_SGI_texture_color_table */ + GLfloat TextureColorTableScale[4]; /**< RGBA */ + GLfloat TextureColorTableBias[4]; /**< RGBA */ +}; + + +/** + * Point attribute group (GL_POINT_BIT). + */ +struct gl_point_attrib +{ + GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */ + GLfloat Size; /**< User-specified point size */ + GLfloat Params[3]; /**< GL_EXT_point_parameters */ + GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */ + GLfloat Threshold; /**< GL_EXT_point_parameters */ + GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */ + GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */ + GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/ + GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */ + GLenum SpriteOrigin; /**< GL_ARB_point_sprite */ +}; + + +/** + * Polygon attribute group (GL_POLYGON_BIT). + */ +struct gl_polygon_attrib +{ + GLenum FrontFace; /**< Either GL_CW or GL_CCW */ + GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */ + GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */ + GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */ + GLboolean CullFlag; /**< Culling on/off flag */ + GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */ + GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */ + GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */ + GLfloat OffsetFactor; /**< Polygon offset factor, from user */ + GLfloat OffsetUnits; /**< Polygon offset units, from user */ + GLboolean OffsetPoint; /**< Offset in GL_POINT mode */ + GLboolean OffsetLine; /**< Offset in GL_LINE mode */ + GLboolean OffsetFill; /**< Offset in GL_FILL mode */ +}; + + +/** + * Scissor attributes (GL_SCISSOR_BIT). + */ +struct gl_scissor_attrib +{ + GLboolean Enabled; /**< Scissor test enabled? */ + GLint X, Y; /**< Lower left corner of box */ + GLsizei Width, Height; /**< Size of box */ +}; + + +/** + * Stencil attribute group (GL_STENCIL_BUFFER_BIT). + * + * Three sets of stencil data are tracked so that OpenGL 2.0, + * GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported + * simultaneously. In each of the stencil state arrays, element 0 corresponds + * to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 / + * GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the + * GL_EXT_stencil_two_side GL_BACK state. + * + * The derived value \c _BackFace is either 1 or 2 depending on whether or + * not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled. + * + * The derived value \c _TestTwoSide is set when the front-face and back-face + * stencil state are different. + */ +struct gl_stencil_attrib +{ + GLboolean Enabled; /**< Enabled flag */ + GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */ + GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */ + GLboolean _Enabled; /**< Enabled and stencil buffer present */ + GLboolean _TestTwoSide; + GLubyte _BackFace; /**< Current back stencil state (1 or 2) */ + GLenum Function[3]; /**< Stencil function */ + GLenum FailFunc[3]; /**< Fail function */ + GLenum ZPassFunc[3]; /**< Depth buffer pass function */ + GLenum ZFailFunc[3]; /**< Depth buffer fail function */ + GLint Ref[3]; /**< Reference value */ + GLuint ValueMask[3]; /**< Value mask */ + GLuint WriteMask[3]; /**< Write mask */ + GLuint Clear; /**< Clear value */ +}; + + +/** + * An index for each type of texture object. These correspond to the GL + * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. + * Note: the order is from highest priority to lowest priority. + */ +typedef enum +{ + TEXTURE_2D_ARRAY_INDEX, + TEXTURE_1D_ARRAY_INDEX, + TEXTURE_CUBE_INDEX, + TEXTURE_3D_INDEX, + TEXTURE_RECT_INDEX, + TEXTURE_2D_INDEX, + TEXTURE_1D_INDEX, + NUM_TEXTURE_TARGETS +} gl_texture_index; + + +/** + * Bit flags for each type of texture object + * Used for Texture.Unit[]._ReallyEnabled flags. + */ +/*@{*/ +#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX) +#define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX) +#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX) +#define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX) +#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX) +#define TEXTURE_2D_BIT (1 << TEXTURE_2D_INDEX) +#define TEXTURE_1D_BIT (1 << TEXTURE_1D_INDEX) +/*@}*/ + + +/** + * TexGenEnabled flags. + */ +/*@{*/ +#define S_BIT 1 +#define T_BIT 2 +#define R_BIT 4 +#define Q_BIT 8 +#define STR_BITS (S_BIT | T_BIT | R_BIT) +/*@}*/ + + +/** + * Bit flag versions of the corresponding GL_ constants. + */ +/*@{*/ +#define TEXGEN_SPHERE_MAP 0x1 +#define TEXGEN_OBJ_LINEAR 0x2 +#define TEXGEN_EYE_LINEAR 0x4 +#define TEXGEN_REFLECTION_MAP_NV 0x8 +#define TEXGEN_NORMAL_MAP_NV 0x10 + +#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \ + TEXGEN_REFLECTION_MAP_NV | \ + TEXGEN_NORMAL_MAP_NV) +#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \ + TEXGEN_REFLECTION_MAP_NV | \ + TEXGEN_NORMAL_MAP_NV | \ + TEXGEN_EYE_LINEAR) +/*@}*/ + + + +/** Tex-gen enabled for texture unit? */ +#define ENABLE_TEXGEN(unit) (1 << (unit)) + +/** Non-identity texture matrix for texture unit? */ +#define ENABLE_TEXMAT(unit) (1 << (unit)) + + +/** + * Texel fetch function prototype. We use texel fetch functions to + * extract RGBA, color indexes and depth components out of 1D, 2D and 3D + * texture images. These functions help to isolate us from the gritty + * details of all the various texture image encodings. + * + * \param texImage texture image. + * \param col texel column. + * \param row texel row. + * \param img texel image level/layer. + * \param texelOut output texel (up to 4 GLchans) + */ +typedef void (*FetchTexelFuncC)( const struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + GLchan *texelOut ); + +/** + * As above, but returns floats. + * Used for depth component images and for upcoming signed/float + * texture images. + */ +typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + GLfloat *texelOut ); + + +typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + const void *texel); + + +/** + * Texture image state. Describes the dimensions of a texture image, + * the texel format and pointers to Texel Fetch functions. + */ +struct gl_texture_image +{ + GLint InternalFormat; /**< Internal format as given by the user */ + GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA, + * GL_LUMINANCE, GL_LUMINANCE_ALPHA, + * GL_INTENSITY, GL_COLOR_INDEX, + * GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT + * only. Used for choosing TexEnv arithmetic. + */ + GLuint TexFormat; /**< The actual format: MESA_FORMAT_x */ + + GLuint Border; /**< 0 or 1 */ + GLuint Width; /**< = 2^WidthLog2 + 2*Border */ + GLuint Height; /**< = 2^HeightLog2 + 2*Border */ + GLuint Depth; /**< = 2^DepthLog2 + 2*Border */ + GLuint Width2; /**< = Width - 2*Border */ + GLuint Height2; /**< = Height - 2*Border */ + GLuint Depth2; /**< = Depth - 2*Border */ + GLuint WidthLog2; /**< = log2(Width2) */ + GLuint HeightLog2; /**< = log2(Height2) */ + GLuint DepthLog2; /**< = log2(Depth2) */ + GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */ + GLfloat WidthScale; /**< used for mipmap LOD computation */ + GLfloat HeightScale; /**< used for mipmap LOD computation */ + GLfloat DepthScale; /**< used for mipmap LOD computation */ + GLboolean IsClientData; /**< Data owned by client? */ + GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */ + + struct gl_texture_object *TexObject; /**< Pointer back to parent object */ + + FetchTexelFuncC FetchTexelc; /**< GLchan texel fetch function pointer */ + FetchTexelFuncF FetchTexelf; /**< Float texel fetch function pointer */ + + GLuint RowStride; /**< Padded width in units of texels */ + GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to + each 2D slice in 'Data', in texels */ + GLvoid *Data; /**< Image data, accessed via FetchTexel() */ + + /** + * \name For device driver: + */ + /*@{*/ + void *DriverData; /**< Arbitrary device driver data */ + /*@}*/ +}; + + +/** + * Indexes for cube map faces. + */ +typedef enum +{ + FACE_POS_X = 0, + FACE_NEG_X = 1, + FACE_POS_Y = 2, + FACE_NEG_Y = 3, + FACE_POS_Z = 4, + FACE_NEG_Z = 5, + MAX_FACES = 6 +} gl_face_index; + + +/** + * Texture object state. Contains the array of mipmap images, border color, + * wrap modes, filter modes, shadow/texcompare state, and the per-texture + * color palette. + */ +struct gl_texture_object +{ + _glthread_Mutex Mutex; /**< for thread safety */ + GLint RefCount; /**< reference count */ + GLuint Name; /**< the user-visible texture object ID */ + GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ + GLfloat Priority; /**< in [0,1] */ + union { + GLfloat f[4]; + GLuint ui[4]; + GLint i[4]; + } BorderColor; /**< Interpreted according to texture format */ + GLenum WrapS; /**< S-axis texture image wrap mode */ + GLenum WrapT; /**< T-axis texture image wrap mode */ + GLenum WrapR; /**< R-axis texture image wrap mode */ + GLenum MinFilter; /**< minification filter */ + GLenum MagFilter; /**< magnification filter */ + GLfloat MinLod; /**< min lambda, OpenGL 1.2 */ + GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */ + GLfloat LodBias; /**< OpenGL 1.4 */ + GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ + GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ + GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ + GLenum CompareMode; /**< GL_ARB_shadow */ + GLenum CompareFunc; /**< GL_ARB_shadow */ + GLfloat CompareFailValue; /**< GL_ARB_shadow_ambient */ + GLenum DepthMode; /**< GL_ARB_depth_texture */ + GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ + GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ + GLint CropRect[4]; /**< GL_OES_draw_texture */ + GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */ + GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */ + GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */ + GLboolean _Complete; /**< Is texture object complete? */ + GLboolean _RenderToTexture; /**< Any rendering to this texture? */ + GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ + GLenum sRGBDecode; + + /** Actual texture images, indexed by [cube face] and [mipmap level] */ + struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS]; + + /** GL_EXT_paletted_texture */ + struct gl_color_table Palette; + + /** + * \name For device driver. + * Note: instead of attaching driver data to this pointer, it's preferable + * to instead use this struct as a base class for your own texture object + * class. Driver->NewTextureObject() can be used to implement the + * allocation. + */ + void *DriverData; /**< Arbitrary device driver data */ +}; + + +/** Up to four combiner sources are possible with GL_NV_texture_env_combine4 */ +#define MAX_COMBINER_TERMS 4 + + +/** + * Texture combine environment state. + */ +struct gl_tex_env_combine_state +{ + GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */ + GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */ + /** Source terms: GL_PRIMARY_COLOR, GL_TEXTURE, etc */ + GLenum SourceRGB[MAX_COMBINER_TERMS]; + GLenum SourceA[MAX_COMBINER_TERMS]; + /** Source operands: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, etc */ + GLenum OperandRGB[MAX_COMBINER_TERMS]; + GLenum OperandA[MAX_COMBINER_TERMS]; + GLuint ScaleShiftRGB; /**< 0, 1 or 2 */ + GLuint ScaleShiftA; /**< 0, 1 or 2 */ + GLuint _NumArgsRGB; /**< Number of inputs used for the RGB combiner */ + GLuint _NumArgsA; /**< Number of inputs used for the A combiner */ +}; + + +/** + * Texture coord generation state. + */ +struct gl_texgen +{ + GLenum Mode; /**< GL_EYE_LINEAR, GL_SPHERE_MAP, etc */ + GLbitfield _ModeBit; /**< TEXGEN_x bit corresponding to Mode */ + GLfloat ObjectPlane[4]; + GLfloat EyePlane[4]; +}; + + +/** + * Texture unit state. Contains enable flags, texture environment/function/ + * combiners, texgen state, pointers to current texture objects and + * post-filter color tables. + */ +struct gl_texture_unit +{ + GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */ + GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */ + + GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */ + GLfloat EnvColor[4]; + + struct gl_texgen GenS; + struct gl_texgen GenT; + struct gl_texgen GenR; + struct gl_texgen GenQ; + GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */ + GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */ + + GLfloat LodBias; /**< for biasing mipmap levels */ + GLenum BumpTarget; + GLfloat RotMatrix[4]; /* 2x2 matrix */ + + /** + * \name GL_EXT_texture_env_combine + */ + struct gl_tex_env_combine_state Combine; + + /** + * Derived state based on \c EnvMode and the \c BaseFormat of the + * currently enabled texture. + */ + struct gl_tex_env_combine_state _EnvMode; + + /** + * Currently enabled combiner state. This will point to either + * \c Combine or \c _EnvMode. + */ + struct gl_tex_env_combine_state *_CurrentCombine; + + /** Current texture object pointers */ + struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS]; + + /** Points to highest priority, complete and enabled texture object */ + struct gl_texture_object *_Current; + + /** GL_SGI_texture_color_table */ + /*@{*/ + struct gl_color_table ColorTable; + struct gl_color_table ProxyColorTable; + GLboolean ColorTableEnabled; + /*@}*/ +}; + + +/** + * Texture attribute group (GL_TEXTURE_BIT). + */ +struct gl_texture_attrib +{ + GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */ + struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; + + struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; + + /** GL_ARB_seamless_cubemap */ + GLboolean CubeMapSeamless; + + /** GL_EXT_shared_texture_palette */ + GLboolean SharedPalette; + struct gl_color_table Palette; + + /** Texture units/samplers used by vertex or fragment texturing */ + GLbitfield _EnabledUnits; + + /** Texture coord units/sets used for fragment texturing */ + GLbitfield _EnabledCoordUnits; + + /** Texture coord units that have texgen enabled */ + GLbitfield _TexGenEnabled; + + /** Texture coord units that have non-identity matrices */ + GLbitfield _TexMatEnabled; + + /** Bitwise-OR of all Texture.Unit[i]._GenFlags */ + GLbitfield _GenFlags; +}; + + +/** + * Transformation attribute group (GL_TRANSFORM_BIT). + */ +struct gl_transform_attrib +{ + GLenum MatrixMode; /**< Matrix mode */ + GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; /**< User clip planes */ + GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /**< derived */ + GLbitfield ClipPlanesEnabled; /**< on/off bitmask */ + GLboolean Normalize; /**< Normalize all normals? */ + GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */ + GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */ + GLboolean DepthClamp; /**< GL_ARB_depth_clamp */ + + GLfloat CullEyePos[4]; + GLfloat CullObjPos[4]; +}; + + +/** + * Viewport attribute group (GL_VIEWPORT_BIT). + */ +struct gl_viewport_attrib +{ + GLint X, Y; /**< position */ + GLsizei Width, Height; /**< size */ + GLfloat Near, Far; /**< Depth buffer range */ + GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */ +}; + + +/** + * GL_ARB_vertex/pixel_buffer_object buffer object + */ +struct gl_buffer_object +{ + _glthread_Mutex Mutex; + GLint RefCount; + GLuint Name; + GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */ + GLsizeiptrARB Size; /**< Size of buffer storage in bytes */ + GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ + /** Fields describing a mapped buffer */ + /*@{*/ + GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */ + GLvoid *Pointer; /**< User-space address of mapping */ + GLintptr Offset; /**< Mapped offset */ + GLsizeiptr Length; /**< Mapped length */ + /*@}*/ + GLboolean Written; /**< Ever written to? (for debugging) */ + GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ +}; + + +/** + * Client pixel packing/unpacking attributes + */ +struct gl_pixelstore_attrib +{ + GLint Alignment; + GLint RowLength; + GLint SkipPixels; + GLint SkipRows; + GLint ImageHeight; + GLint SkipImages; + GLboolean SwapBytes; + GLboolean LsbFirst; + GLboolean ClientStorage; /**< GL_APPLE_client_storage */ + GLboolean Invert; /**< GL_MESA_pack_invert */ + struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */ +}; + + +/** + * Client vertex array attributes + */ +struct gl_client_array +{ + GLint Size; /**< components per element (1,2,3,4) */ + GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */ + GLenum Format; /**< default: GL_RGBA, but may be GL_BGRA */ + GLsizei Stride; /**< user-specified stride */ + GLsizei StrideB; /**< actual stride in bytes */ + const GLubyte *Ptr; /**< Points to array data */ + GLboolean Enabled; /**< Enabled flag is a boolean */ + GLboolean Normalized; /**< GL_ARB_vertex_program */ + GLboolean Integer; /**< Integer-valued? */ + GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */ + GLuint _ElementSize; /**< size of each element in bytes */ + + struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */ + GLuint _MaxElement; /**< max element index into array buffer + 1 */ +}; + + +/** + * Collection of vertex arrays. Defined by the GL_APPLE_vertex_array_object + * extension, but a nice encapsulation in any case. + */ +struct gl_array_object +{ + /** Name of the array object as received from glGenVertexArrayAPPLE. */ + GLuint Name; + + GLint RefCount; + _glthread_Mutex Mutex; + GLboolean VBOonly; /**< require all arrays to live in VBOs? */ + + /** Conventional vertex arrays */ + /*@{*/ + struct gl_client_array Vertex; + struct gl_client_array Weight; + struct gl_client_array Normal; + struct gl_client_array Color; + struct gl_client_array SecondaryColor; + struct gl_client_array FogCoord; + struct gl_client_array Index; + struct gl_client_array EdgeFlag; + struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; + struct gl_client_array PointSize; + /*@}*/ + + /** + * Generic arrays for vertex programs/shaders. + * For NV vertex programs, these attributes alias and take priority + * over the conventional attribs above. For ARB vertex programs and + * GLSL vertex shaders, these attributes are separate. + */ + struct gl_client_array VertexAttrib[MAX_VERTEX_GENERIC_ATTRIBS]; + + /** Mask of _NEW_ARRAY_* values indicating which arrays are enabled */ + GLbitfield _Enabled; + + /** + * Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs + * we can determine the max legal (in bounds) glDrawElements array index. + */ + GLuint _MaxElement; +}; + + +/** + * Vertex array state + */ +struct gl_array_attrib +{ + /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */ + struct gl_array_object *ArrayObj; + + /** The default vertex array object */ + struct gl_array_object *DefaultArrayObj; + + /** Array objects (GL_ARB/APPLE_vertex_array_object) */ + struct _mesa_HashTable *Objects; + + GLint ActiveTexture; /**< Client Active Texture */ + GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */ + GLuint LockCount; /**< GL_EXT_compiled_vertex_array */ + + /** GL 3.1 (slightly different from GL_NV_primitive_restart) */ + GLboolean PrimitiveRestart; + GLuint RestartIndex; + + GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */ + + /* GL_ARB_vertex_buffer_object */ + struct gl_buffer_object *ArrayBufferObj; + struct gl_buffer_object *ElementArrayBufferObj; +}; + + +/** + * Feedback buffer state + */ +struct gl_feedback +{ + GLenum Type; + GLbitfield _Mask; /**< FB_* bits */ + GLfloat *Buffer; + GLuint BufferSize; + GLuint Count; +}; + + +/** + * Selection buffer state + */ +struct gl_selection +{ + GLuint *Buffer; /**< selection buffer */ + GLuint BufferSize; /**< size of the selection buffer */ + GLuint BufferCount; /**< number of values in the selection buffer */ + GLuint Hits; /**< number of records in the selection buffer */ + GLuint NameStackDepth; /**< name stack depth */ + GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */ + GLboolean HitFlag; /**< hit flag */ + GLfloat HitMinZ; /**< minimum hit depth */ + GLfloat HitMaxZ; /**< maximum hit depth */ +}; + + +/** + * 1-D Evaluator control points + */ +struct gl_1d_map +{ + GLuint Order; /**< Number of control points */ + GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */ + GLfloat *Points; /**< Points to contiguous control points */ +}; + + +/** + * 2-D Evaluator control points + */ +struct gl_2d_map +{ + GLuint Uorder; /**< Number of control points in U dimension */ + GLuint Vorder; /**< Number of control points in V dimension */ + GLfloat u1, u2, du; + GLfloat v1, v2, dv; + GLfloat *Points; /**< Points to contiguous control points */ +}; + + +/** + * All evaluator control point state + */ +struct gl_evaluators +{ + /** + * \name 1-D maps + */ + /*@{*/ + struct gl_1d_map Map1Vertex3; + struct gl_1d_map Map1Vertex4; + struct gl_1d_map Map1Index; + struct gl_1d_map Map1Color4; + struct gl_1d_map Map1Normal; + struct gl_1d_map Map1Texture1; + struct gl_1d_map Map1Texture2; + struct gl_1d_map Map1Texture3; + struct gl_1d_map Map1Texture4; + struct gl_1d_map Map1Attrib[16]; /**< GL_NV_vertex_program */ + /*@}*/ + + /** + * \name 2-D maps + */ + /*@{*/ + struct gl_2d_map Map2Vertex3; + struct gl_2d_map Map2Vertex4; + struct gl_2d_map Map2Index; + struct gl_2d_map Map2Color4; + struct gl_2d_map Map2Normal; + struct gl_2d_map Map2Texture1; + struct gl_2d_map Map2Texture2; + struct gl_2d_map Map2Texture3; + struct gl_2d_map Map2Texture4; + struct gl_2d_map Map2Attrib[16]; /**< GL_NV_vertex_program */ + /*@}*/ +}; + + +/** + * Names of the various vertex/fragment program register files, etc. + * + * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) + * All values should fit in a 4-bit field. + * + * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM, + * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to + * be "uniform" variables since they can only be set outside glBegin/End. + * They're also all stored in the same Parameters array. + */ +typedef enum +{ + PROGRAM_TEMPORARY, /**< machine->Temporary[] */ + PROGRAM_INPUT, /**< machine->Inputs[] */ + PROGRAM_OUTPUT, /**< machine->Outputs[] */ + PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */ + PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */ + PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */ + PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */ + PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */ + PROGRAM_CONSTANT, /**< gl_program->Parameters[] */ + PROGRAM_UNIFORM, /**< gl_program->Parameters[] */ + PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */ + PROGRAM_ADDRESS, /**< machine->AddressReg */ + PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */ + PROGRAM_SYSTEM_VALUE,/**< InstanceId, PrimitiveID, etc. */ + PROGRAM_UNDEFINED, /**< Invalid/TBD value */ + PROGRAM_FILE_MAX +} gl_register_file; + + +/** + * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be + * one of these values. + */ +typedef enum +{ + SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */ + SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */ + SYSTEM_VALUE_MAX /**< Number of values */ +} gl_system_value; + + +/** Vertex and fragment instructions */ +struct prog_instruction; +struct gl_program_parameter_list; +struct gl_uniform_list; + + +/** + * Base class for any kind of program object + */ +struct gl_program +{ + GLuint Id; + GLubyte *String; /**< Null-terminated program text */ + GLint RefCount; + GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */ + GLenum Format; /**< String encoding format */ + GLboolean Resident; + + struct prog_instruction *Instructions; + + GLbitfield InputsRead; /**< Bitmask of which input regs are read */ + GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */ + GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */ + GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */ + GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */ + GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */ + GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */ + GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */ + + + /** Named parameters, constants, etc. from program text */ + struct gl_program_parameter_list *Parameters; + /** Numbered local parameters */ + GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4]; + + /** Vertex/fragment shader varying vars */ + struct gl_program_parameter_list *Varying; + /** Vertex program user-defined attributes */ + struct gl_program_parameter_list *Attributes; + + /** Map from sampler unit to texture unit (set by glUniform1i()) */ + GLubyte SamplerUnits[MAX_SAMPLERS]; + /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */ + gl_texture_index SamplerTargets[MAX_SAMPLERS]; + + /** Bitmask of which register files are read/written with indirect + * addressing. Mask of (1 << PROGRAM_x) bits. + */ + GLbitfield IndirectRegisterFiles; + + /** Logical counts */ + /*@{*/ + GLuint NumInstructions; + GLuint NumTemporaries; + GLuint NumParameters; + GLuint NumAttributes; + GLuint NumAddressRegs; + GLuint NumAluInstructions; + GLuint NumTexInstructions; + GLuint NumTexIndirections; + /*@}*/ + /** Native, actual h/w counts */ + /*@{*/ + GLuint NumNativeInstructions; + GLuint NumNativeTemporaries; + GLuint NumNativeParameters; + GLuint NumNativeAttributes; + GLuint NumNativeAddressRegs; + GLuint NumNativeAluInstructions; + GLuint NumNativeTexInstructions; + GLuint NumNativeTexIndirections; + /*@}*/ +}; + + +/** Vertex program object */ +struct gl_vertex_program +{ + struct gl_program Base; /**< base class */ + GLboolean IsNVProgram; /**< is this a GL_NV_vertex_program program? */ + GLboolean IsPositionInvariant; +}; + + +/** Geometry program object */ +struct gl_geometry_program +{ + struct gl_program Base; /**< base class */ + + GLint VerticesOut; + GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, + GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ + GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ +}; + + +/** Fragment program object */ +struct gl_fragment_program +{ + struct gl_program Base; /**< base class */ + GLenum FogOption; + GLboolean UsesKill; /**< shader uses KIL instruction */ + GLboolean OriginUpperLeft; + GLboolean PixelCenterInteger; +}; + + +/** + * State common to vertex and fragment programs. + */ +struct gl_program_state +{ + GLint ErrorPos; /* GL_PROGRAM_ERROR_POSITION_ARB/NV */ + const char *ErrorString; /* GL_PROGRAM_ERROR_STRING_ARB/NV */ +}; + + +/** + * Context state for vertex programs. + */ +struct gl_vertex_program_state +{ + GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */ + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ + GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ + GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ + struct gl_vertex_program *Current; /**< User-bound vertex program */ + + /** Currently enabled and valid vertex program (including internal + * programs, user-defined vertex programs and GLSL vertex shaders). + * This is the program we must use when rendering. + */ + struct gl_vertex_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ + + /* For GL_NV_vertex_program only: */ + GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4]; + GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4]; + + /** Should fixed-function T&L be implemented with a vertex prog? */ + GLboolean _MaintainTnlProgram; + + /** Program to emulate fixed-function T&L (see above) */ + struct gl_vertex_program *_TnlProgram; + + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; + + GLboolean _Overriden; +}; + + +/** + * Context state for geometry programs. + */ +struct gl_geometry_program_state +{ + GLboolean Enabled; /**< GL_ARB_GEOMETRY_SHADER4 */ + GLboolean _Enabled; /**< Enabled and valid program? */ + struct gl_geometry_program *Current; /**< user-bound geometry program */ + + /** Currently enabled and valid program (including internal programs + * and compiled shader programs). + */ + struct gl_geometry_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ + + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; +}; + +/** + * Context state for fragment programs. + */ +struct gl_fragment_program_state +{ + GLboolean Enabled; /**< User-set fragment program enable flag */ + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ + struct gl_fragment_program *Current; /**< User-bound fragment program */ + + /** Currently enabled and valid fragment program (including internal + * programs, user-defined fragment programs and GLSL fragment shaders). + * This is the program we must use when rendering. + */ + struct gl_fragment_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ + + /** Should fixed-function texturing be implemented with a fragment prog? */ + GLboolean _MaintainTexEnvProgram; + + /** Program to emulate fixed-function texture env/combine (see above) */ + struct gl_fragment_program *_TexEnvProgram; + + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; +}; + + +/** + * ATI_fragment_shader runtime state + */ +#define ATI_FS_INPUT_PRIMARY 0 +#define ATI_FS_INPUT_SECONDARY 1 + +struct atifs_instruction; +struct atifs_setupinst; + +/** + * ATI fragment shader + */ +struct ati_fragment_shader +{ + GLuint Id; + GLint RefCount; + struct atifs_instruction *Instructions[2]; + struct atifs_setupinst *SetupInst[2]; + GLfloat Constants[8][4]; + GLbitfield LocalConstDef; /**< Indicates which constants have been set */ + GLubyte numArithInstr[2]; + GLubyte regsAssigned[2]; + GLubyte NumPasses; /**< 1 or 2 */ + GLubyte cur_pass; + GLubyte last_optype; + GLboolean interpinp1; + GLboolean isValid; + GLuint swizzlerq; +}; + +/** + * Context state for GL_ATI_fragment_shader + */ +struct gl_ati_fragment_shader_state +{ + GLboolean Enabled; + GLboolean _Enabled; /**< enabled and valid shader? */ + GLboolean Compiling; + GLfloat GlobalConstants[8][4]; + struct ati_fragment_shader *Current; +}; + + +/** + * Occlusion/timer query object. + */ +struct gl_query_object +{ + GLenum Target; /**< The query target, when active */ + GLuint Id; /**< hash table ID/name */ + GLuint64EXT Result; /**< the counter */ + GLboolean Active; /**< inside Begin/EndQuery */ + GLboolean Ready; /**< result is ready? */ +}; + + +/** + * Context state for query objects. + */ +struct gl_query_state +{ + struct _mesa_HashTable *QueryObjects; + struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */ + struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */ + + /** GL_NV_conditional_render */ + struct gl_query_object *CondRenderQuery; + + /** GL_EXT_transform_feedback */ + struct gl_query_object *PrimitivesGenerated; + struct gl_query_object *PrimitivesWritten; + + /** GL_ARB_timer_query */ + struct gl_query_object *TimeElapsed; + + GLenum CondRenderMode; +}; + + +/** Sync object state */ +struct gl_sync_object { + struct simple_node link; + GLenum Type; /**< GL_SYNC_FENCE */ + GLuint Name; /**< Fence name */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; /**< Object was deleted while there were still + * live references (e.g., sync not yet finished) + */ + GLenum SyncCondition; + GLbitfield Flags; /**< Flags passed to glFenceSync */ + GLuint StatusFlag:1; /**< Has the sync object been signaled? */ +}; + + +/** Set by #pragma directives */ +struct gl_sl_pragmas +{ + GLboolean IgnoreOptimize; /**< ignore #pragma optimize(on/off) ? */ + GLboolean IgnoreDebug; /**< ignore #pragma debug(on/off) ? */ + GLboolean Optimize; /**< defaults on */ + GLboolean Debug; /**< defaults off */ +}; + + +/** + * A GLSL vertex or fragment shader object. + */ +struct gl_shader +{ + GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB (first field!) */ + GLuint Name; /**< AKA the handle */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; + GLboolean CompileStatus; + GLboolean Main; /**< shader defines main() */ + GLboolean UnresolvedRefs; + const GLchar *Source; /**< Source code string */ + GLuint SourceChecksum; /**< for debug/logging purposes */ + struct gl_program *Program; /**< Post-compile assembly code */ + GLchar *InfoLog; + struct gl_sl_pragmas Pragmas; + + unsigned Version; /**< GLSL version used for linking */ + + struct exec_list *ir; + struct glsl_symbol_table *symbols; + + /** Shaders containing built-in functions that are used for linking. */ + struct gl_shader *builtins_to_link[16]; + unsigned num_builtins_to_link; +}; + + +/** + * A GLSL program object. + * Basically a linked collection of vertex and fragment shaders. + */ +struct gl_shader_program +{ + GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */ + GLuint Name; /**< aka handle or ID */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; + + GLuint NumShaders; /**< number of attached shaders */ + struct gl_shader **Shaders; /**< List of attached the shaders */ + + /** User-defined attribute bindings (glBindAttribLocation) */ + struct gl_program_parameter_list *Attributes; + + /** Transform feedback varyings */ + struct { + GLenum BufferMode; + GLuint NumVarying; + GLchar **VaryingNames; /**< Array [NumVarying] of char * */ + } TransformFeedback; + + /** Geometry shader state - copied into gl_geometry_program at link time */ + struct { + GLint VerticesOut; + GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, + GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ + GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ + } Geom; + + /* post-link info: */ + struct gl_vertex_program *VertexProgram; /**< Linked vertex program */ + struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */ + struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */ + struct gl_uniform_list *Uniforms; + struct gl_program_parameter_list *Varying; + GLboolean LinkStatus; /**< GL_LINK_STATUS */ + GLboolean Validated; + GLboolean _Used; /**< Ever used for drawing? */ + GLchar *InfoLog; + + unsigned Version; /**< GLSL version used for linking */ + + /** + * Per-stage shaders resulting from the first stage of linking. + * + * Set of linked shaders for this program. The array is accessed using the + * \c MESA_SHADER_* defines. Entries for non-existent stages will be + * \c NULL. + */ + struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES]; +}; + + +#define GLSL_DUMP 0x1 /**< Dump shaders to stdout */ +#define GLSL_LOG 0x2 /**< Write shaders to files */ +#define GLSL_OPT 0x4 /**< Force optimizations (override pragmas) */ +#define GLSL_NO_OPT 0x8 /**< Force no optimizations (override pragmas) */ +#define GLSL_UNIFORMS 0x10 /**< Print glUniform calls */ +#define GLSL_NOP_VERT 0x20 /**< Force no-op vertex shaders */ +#define GLSL_NOP_FRAG 0x40 /**< Force no-op fragment shaders */ +#define GLSL_USE_PROG 0x80 /**< Log glUseProgram calls */ + + +/** + * Context state for GLSL vertex/fragment shaders. + */ +struct gl_shader_state +{ + /** + * Programs used for rendering + * + * There is a separate program set for each shader stage. If + * GL_EXT_separate_shader_objects is not supported, each of these must point + * to \c NULL or to the same program. + */ + struct gl_shader_program *CurrentVertexProgram; + struct gl_shader_program *CurrentGeometryProgram; + struct gl_shader_program *CurrentFragmentProgram; + + /** + * Program used by glUniform calls. + * + * Explicitly set by \c glUseProgram and \c glActiveProgramEXT. + */ + struct gl_shader_program *ActiveProgram; + + void *MemPool; + + GLbitfield Flags; /**< Mask of GLSL_x flags */ +}; + +/** + * Compiler options for a single GLSL shaders type + */ +struct gl_shader_compiler_options +{ + /** Driver-selectable options: */ + GLboolean EmitCondCodes; /**< Use condition codes? */ + GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */ + /** + * Attempts to flatten all ir_if (OPCODE_IF) for GPUs that can't + * support control flow. + */ + GLboolean EmitNoIfs; + GLboolean EmitNoLoops; + GLboolean EmitNoFunctions; + GLboolean EmitNoCont; /**< Emit CONT opcode? */ + GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */ + GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */ + GLboolean EmitNoPow; /**< Emit POW opcodes? */ + + /** + * \name Forms of indirect addressing the driver cannot do. + */ + /*@{*/ + GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */ + GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */ + GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */ + GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */ + /*@}*/ + + GLuint MaxUnrollIterations; + + struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */ +}; + +/** + * Transform feedback object state + */ +struct gl_transform_feedback_object +{ + GLuint Name; /**< AKA the object ID */ + GLint RefCount; + GLboolean Active; /**< Is transform feedback enabled? */ + GLboolean Paused; /**< Is transform feedback paused? */ + + /** The feedback buffers */ + GLuint BufferNames[MAX_FEEDBACK_ATTRIBS]; + struct gl_buffer_object *Buffers[MAX_FEEDBACK_ATTRIBS]; + + /** Start of feedback data in dest buffer */ + GLintptr Offset[MAX_FEEDBACK_ATTRIBS]; + /** Max data to put into dest buffer (in bytes) */ + GLsizeiptr Size[MAX_FEEDBACK_ATTRIBS]; +}; + + +/** + * Context state for transform feedback. + */ +struct gl_transform_feedback +{ + GLenum Mode; /**< GL_POINTS, GL_LINES or GL_TRIANGLES */ + + GLboolean RasterDiscard; /**< GL_RASTERIZER_DISCARD */ + + /** The general binding point (GL_TRANSFORM_FEEDBACK_BUFFER) */ + struct gl_buffer_object *CurrentBuffer; + + /** The table of all transform feedback objects */ + struct _mesa_HashTable *Objects; + + /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */ + struct gl_transform_feedback_object *CurrentObject; + + /** The default xform-fb object (Name==0) */ + struct gl_transform_feedback_object *DefaultObject; +}; + + + +/** + * State which can be shared by multiple contexts: + */ +struct gl_shared_state +{ + _glthread_Mutex Mutex; /**< for thread safety */ + GLint RefCount; /**< Reference count */ + struct _mesa_HashTable *DisplayList; /**< Display lists hash table */ + struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */ + + /** Default texture objects (shared by all texture units) */ + struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS]; + + /** Fallback texture used when a bound texture is incomplete */ + struct gl_texture_object *FallbackTex; + + /** + * \name Thread safety and statechange notification for texture + * objects. + * + * \todo Improve the granularity of locking. + */ + /*@{*/ + _glthread_Mutex TexMutex; /**< texobj thread safety */ + GLuint TextureStateStamp; /**< state notification for shared tex */ + /*@}*/ + + /** Default buffer object for vertex arrays that aren't in VBOs */ + struct gl_buffer_object *NullBufferObj; + + /** + * \name Vertex/geometry/fragment programs + */ + /*@{*/ + struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */ + struct gl_vertex_program *DefaultVertexProgram; + struct gl_fragment_program *DefaultFragmentProgram; + struct gl_geometry_program *DefaultGeometryProgram; + /*@}*/ + + /* GL_ATI_fragment_shader */ + struct _mesa_HashTable *ATIShaders; + struct ati_fragment_shader *DefaultFragmentShader; + + struct _mesa_HashTable *BufferObjects; + + /** Table of both gl_shader and gl_shader_program objects */ + struct _mesa_HashTable *ShaderObjects; + + /* GL_EXT_framebuffer_object */ + struct _mesa_HashTable *RenderBuffers; + struct _mesa_HashTable *FrameBuffers; + + /* GL_ARB_sync */ + struct simple_node SyncObjects; + + void *DriverData; /**< Device driver shared state */ +}; + + + + +/** + * A renderbuffer stores colors or depth values or stencil values. + * A framebuffer object will have a collection of these. + * Data are read/written to the buffer with a handful of Get/Put functions. + * + * Instances of this object are allocated with the Driver's NewRenderbuffer + * hook. Drivers will likely wrap this class inside a driver-specific + * class to simulate inheritance. + */ +struct gl_renderbuffer +{ +#define RB_MAGIC 0xaabbccdd + int Magic; /** XXX TEMPORARY DEBUG INFO */ + _glthread_Mutex Mutex; /**< for thread safety */ + GLuint ClassID; /**< Useful for drivers */ + GLuint Name; + GLint RefCount; + GLuint Width, Height; + GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ + + GLenum InternalFormat; /**< The user-specified format */ + GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or + GL_STENCIL_INDEX. */ + GLuint Format; /**< The actual format: MESA_FORMAT_x */ + + GLubyte NumSamples; + + GLenum DataType; /**< Type of values passed to the Get/Put functions */ + GLvoid *Data; /**< This may not be used by some kinds of RBs */ + + /* Used to wrap one renderbuffer around another: */ + struct gl_renderbuffer *Wrapped; + + /* Delete this renderbuffer */ + void (*Delete)(struct gl_renderbuffer *rb); + + /* Allocate new storage for this renderbuffer */ + GLboolean (*AllocStorage)(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height); + + /* Lock/Unlock are called before/after calling the Get/Put functions. + * Not sure this is the right place for these yet. + void (*Lock)(struct gl_context *ctx, struct gl_renderbuffer *rb); + void (*Unlock)(struct gl_context *ctx, struct gl_renderbuffer *rb); + */ + + /* Return a pointer to the element/pixel at (x,y). + * Should return NULL if the buffer memory can't be directly addressed. + */ + void *(*GetPointer)(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y); + + /* Get/Read a row of values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*GetRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values); + + /* Get/Read values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*GetValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values); + + /* Put/Write a row of values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask); + + /* Put/Write a row of RGB values. This is a special-case routine that's + * only used for RGBA renderbuffers when the source data is GL_RGB. That's + * a common case for glDrawPixels and some triangle routines. + * The values will be of format GL_RGB and type DataType. + */ + void (*PutRowRGB)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask); + + + /* Put/Write a row of identical values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutMonoRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask); + + /* Put/Write values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask); + /* Put/Write identical values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutMonoValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask); +}; + + +/** + * A renderbuffer attachment points to either a texture object (and specifies + * a mipmap level, cube face or 3D texture slice) or points to a renderbuffer. + */ +struct gl_renderbuffer_attachment +{ + GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */ + GLboolean Complete; + + /** + * If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the + * application supplied renderbuffer object. + */ + struct gl_renderbuffer *Renderbuffer; + + /** + * If \c Type is \c GL_TEXTURE, this stores a pointer to the application + * supplied texture object. + */ + struct gl_texture_object *Texture; + GLuint TextureLevel; /**< Attached mipmap level. */ + GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */ + GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D + * and 2D array textures */ +}; + + +/** + * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc). + * In C++ terms, think of this as a base class from which device drivers + * will make derived classes. + */ +struct gl_framebuffer +{ + _glthread_Mutex Mutex; /**< for thread safety */ + /** + * If zero, this is a window system framebuffer. If non-zero, this + * is a FBO framebuffer; note that for some devices (i.e. those with + * a natural pixel coordinate system for FBOs that differs from the + * OpenGL/Mesa coordinate system), this means that the viewport, + * polygon face orientation, and polygon stipple will have to be inverted. + */ + GLuint Name; + + GLint RefCount; + GLboolean DeletePending; + + /** + * The framebuffer's visual. Immutable if this is a window system buffer. + * Computed from attachments if user-made FBO. + */ + struct gl_config Visual; + + GLboolean Initialized; + + GLuint Width, Height; /**< size of frame buffer in pixels */ + + /** \name Drawing bounds (Intersection of buffer size and scissor box) */ + /*@{*/ + GLint _Xmin, _Xmax; /**< inclusive */ + GLint _Ymin, _Ymax; /**< exclusive */ + /*@}*/ + + /** \name Derived Z buffer stuff */ + /*@{*/ + GLuint _DepthMax; /**< Max depth buffer value */ + GLfloat _DepthMaxF; /**< Float max depth buffer value */ + GLfloat _MRD; /**< minimum resolvable difference in Z values */ + /*@}*/ + + /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */ + GLenum _Status; + + /** Integer color values */ + GLboolean _IntegerColor; + + /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ + struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; + + /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER + * attribute group and GL_PIXEL attribute group, respectively. + */ + GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS]; + GLenum ColorReadBuffer; + + /** Computed from ColorDraw/ReadBuffer above */ + GLuint _NumColorDrawBuffers; + GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */ + GLint _ColorReadBufferIndex; /* -1 = None */ + struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS]; + struct gl_renderbuffer *_ColorReadBuffer; + + /** The Actual depth/stencil buffers to use. May be wrappers around the + * depth/stencil buffers attached above. */ + struct gl_renderbuffer *_DepthBuffer; + struct gl_renderbuffer *_StencilBuffer; + + /** Delete this framebuffer */ + void (*Delete)(struct gl_framebuffer *fb); +}; + + +/** + * Precision info for shader datatypes. See glGetShaderPrecisionFormat(). + */ +struct gl_precision +{ + GLushort RangeMin; /**< min value exponent */ + GLushort RangeMax; /**< max value exponent */ + GLushort Precision; /**< number of mantissa bits */ +}; + + +/** + * Limits for vertex and fragment programs/shaders. + */ +struct gl_program_constants +{ + /* logical limits */ + GLuint MaxInstructions; + GLuint MaxAluInstructions; + GLuint MaxTexInstructions; + GLuint MaxTexIndirections; + GLuint MaxAttribs; + GLuint MaxTemps; + GLuint MaxAddressRegs; + GLuint MaxParameters; + GLuint MaxLocalParams; + GLuint MaxEnvParams; + /* native/hardware limits */ + GLuint MaxNativeInstructions; + GLuint MaxNativeAluInstructions; + GLuint MaxNativeTexInstructions; + GLuint MaxNativeTexIndirections; + GLuint MaxNativeAttribs; + GLuint MaxNativeTemps; + GLuint MaxNativeAddressRegs; + GLuint MaxNativeParameters; + /* For shaders */ + GLuint MaxUniformComponents; + /* GL_ARB_geometry_shader4 */ + GLuint MaxGeometryTextureImageUnits; + GLuint MaxGeometryVaryingComponents; + GLuint MaxVertexVaryingComponents; + GLuint MaxGeometryUniformComponents; + GLuint MaxGeometryOutputVertices; + GLuint MaxGeometryTotalOutputComponents; + /* ES 2.0 and GL_ARB_ES2_compatibility */ + struct gl_precision LowFloat, MediumFloat, HighFloat; + struct gl_precision LowInt, MediumInt, HighInt; +}; + + +/** + * Constants which may be overridden by device driver during context creation + * but are never changed after that. + */ +struct gl_constants +{ + GLint MaxTextureMbytes; /**< Max memory per image, in MB */ + GLint MaxTextureLevels; /**< Max mipmap levels. */ + GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */ + GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */ + GLint MaxArrayTextureLayers; /**< Max layers in array textures */ + GLint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */ + GLuint MaxTextureCoordUnits; + GLuint MaxTextureImageUnits; + GLuint MaxVertexTextureImageUnits; + GLuint MaxCombinedTextureImageUnits; + GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */ + GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ + GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */ + + GLuint MaxArrayLockSize; + + GLint SubPixelBits; + + GLfloat MinPointSize, MaxPointSize; /**< aliased */ + GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */ + GLfloat PointSizeGranularity; + GLfloat MinLineWidth, MaxLineWidth; /**< aliased */ + GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */ + GLfloat LineWidthGranularity; + + GLuint MaxColorTableSize; + + GLuint MaxClipPlanes; + GLuint MaxLights; + GLfloat MaxShininess; /**< GL_NV_light_max_exponent */ + GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */ + + GLuint MaxViewportWidth, MaxViewportHeight; + + struct gl_program_constants VertexProgram; /**< GL_ARB_vertex_program */ + struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */ + struct gl_program_constants GeometryProgram; /**< GL_ARB_geometry_shader4 */ + GLuint MaxProgramMatrices; + GLuint MaxProgramMatrixStackDepth; + + /** vertex array / buffer object bounds checking */ + GLboolean CheckArrayBounds; + + GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */ + + GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */ + GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */ + GLuint MaxSamples; /**< GL_ARB_framebuffer_object */ + + GLuint MaxVarying; /**< Number of float[4] varying parameters */ + + GLuint GLSLVersion; /**< GLSL version supported (ex: 120 = 1.20) */ + + /** Which texture units support GL_ATI_envmap_bumpmap as targets */ + GLbitfield SupportedBumpUnits; + + /** + * Maximum amount of time, measured in nanseconds, that the server can wait. + */ + GLuint64 MaxServerWaitTimeout; + + /** GL_EXT_provoking_vertex */ + GLboolean QuadsFollowProvokingVertexConvention; + + /** OpenGL version 3.0 */ + GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */ + + /** OpenGL version 3.2 */ + GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */ + + /** GL_EXT_transform_feedback */ + GLuint MaxTransformFeedbackSeparateAttribs; + GLuint MaxTransformFeedbackSeparateComponents; + GLuint MaxTransformFeedbackInterleavedComponents; + + /** GL_EXT_gpu_shader4 */ + GLint MinProgramTexelOffset, MaxProgramTexelOffset; +}; + + +/** + * Enable flag for each OpenGL extension. Different device drivers will + * enable different extensions at runtime. + */ +struct gl_extensions +{ + GLboolean dummy; /* don't remove this! */ + GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */ + GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */ + GLboolean ARB_ES2_compatibility; + GLboolean ARB_blend_func_extended; + GLboolean ARB_copy_buffer; + GLboolean ARB_depth_buffer_float; + GLboolean ARB_depth_clamp; + GLboolean ARB_depth_texture; + GLboolean ARB_draw_buffers; + GLboolean ARB_draw_buffers_blend; + GLboolean ARB_draw_elements_base_vertex; + GLboolean ARB_draw_instanced; + GLboolean ARB_fragment_coord_conventions; + GLboolean ARB_fragment_program; + GLboolean ARB_fragment_program_shadow; + GLboolean ARB_fragment_shader; + GLboolean ARB_framebuffer_object; + GLboolean ARB_explicit_attrib_location; + GLboolean ARB_geometry_shader4; + GLboolean ARB_half_float_pixel; + GLboolean ARB_half_float_vertex; + GLboolean ARB_instanced_arrays; + GLboolean ARB_map_buffer_range; + GLboolean ARB_multisample; + GLboolean ARB_multitexture; + GLboolean ARB_occlusion_query; + GLboolean ARB_occlusion_query2; + GLboolean ARB_point_sprite; + GLboolean ARB_sampler_objects; + GLboolean ARB_seamless_cube_map; + GLboolean ARB_shader_objects; + GLboolean ARB_shader_stencil_export; + GLboolean ARB_shading_language_100; + GLboolean ARB_shadow; + GLboolean ARB_shadow_ambient; + GLboolean ARB_sync; + GLboolean ARB_texture_border_clamp; + GLboolean ARB_texture_buffer_object; + GLboolean ARB_texture_compression; + GLboolean ARB_texture_compression_rgtc; + GLboolean ARB_texture_cube_map; + GLboolean ARB_texture_env_combine; + GLboolean ARB_texture_env_crossbar; + GLboolean ARB_texture_env_dot3; + GLboolean ARB_texture_float; + GLboolean ARB_texture_mirrored_repeat; + GLboolean ARB_texture_multisample; + GLboolean ARB_texture_non_power_of_two; + GLboolean ARB_texture_rg; + GLboolean ARB_texture_rgb10_a2ui; + GLboolean ARB_timer_query; + GLboolean ARB_transform_feedback2; + GLboolean ARB_transpose_matrix; + GLboolean ARB_uniform_buffer_object; + GLboolean ARB_vertex_array_object; + GLboolean ARB_vertex_buffer_object; + GLboolean ARB_vertex_program; + GLboolean ARB_vertex_shader; + GLboolean ARB_vertex_type_2_10_10_10_rev; + GLboolean ARB_window_pos; + GLboolean EXT_abgr; + GLboolean EXT_bgra; + GLboolean EXT_blend_color; + GLboolean EXT_blend_equation_separate; + GLboolean EXT_blend_func_separate; + GLboolean EXT_blend_logic_op; + GLboolean EXT_blend_minmax; + GLboolean EXT_blend_subtract; + GLboolean EXT_clip_volume_hint; + GLboolean EXT_compiled_vertex_array; + GLboolean EXT_copy_texture; + GLboolean EXT_depth_bounds_test; + GLboolean EXT_draw_buffers2; + GLboolean EXT_draw_range_elements; + GLboolean EXT_fog_coord; + GLboolean EXT_framebuffer_blit; + GLboolean EXT_framebuffer_multisample; + GLboolean EXT_framebuffer_object; + GLboolean EXT_framebuffer_sRGB; + GLboolean EXT_gpu_program_parameters; + GLboolean EXT_gpu_shader4; + GLboolean EXT_multi_draw_arrays; + GLboolean EXT_paletted_texture; + GLboolean EXT_packed_depth_stencil; + GLboolean EXT_packed_float; + GLboolean EXT_packed_pixels; + GLboolean EXT_pixel_buffer_object; + GLboolean EXT_point_parameters; + GLboolean EXT_polygon_offset; + GLboolean EXT_provoking_vertex; + GLboolean EXT_rescale_normal; + GLboolean EXT_shadow_funcs; + GLboolean EXT_secondary_color; + GLboolean EXT_separate_shader_objects; + GLboolean EXT_separate_specular_color; + GLboolean EXT_shared_texture_palette; + GLboolean EXT_stencil_wrap; + GLboolean EXT_stencil_two_side; + GLboolean EXT_subtexture; + GLboolean EXT_texture; + GLboolean EXT_texture_object; + GLboolean EXT_texture3D; + GLboolean EXT_texture_array; + GLboolean EXT_texture_compression_s3tc; + GLboolean EXT_texture_env_add; + GLboolean EXT_texture_env_combine; + GLboolean EXT_texture_env_dot3; + GLboolean EXT_texture_filter_anisotropic; + GLboolean EXT_texture_integer; + GLboolean EXT_texture_lod_bias; + GLboolean EXT_texture_mirror_clamp; + GLboolean EXT_texture_shared_exponent; + GLboolean EXT_texture_sRGB; + GLboolean EXT_texture_sRGB_decode; + GLboolean EXT_texture_swizzle; + GLboolean EXT_transform_feedback; + GLboolean EXT_timer_query; + GLboolean EXT_vertex_array; + GLboolean EXT_vertex_array_bgra; + GLboolean EXT_vertex_array_set; + GLboolean OES_standard_derivatives; + /* vendor extensions */ + GLboolean APPLE_client_storage; + GLboolean APPLE_packed_pixels; + GLboolean APPLE_vertex_array_object; + GLboolean APPLE_object_purgeable; + GLboolean ATI_envmap_bumpmap; + GLboolean ATI_texture_mirror_once; + GLboolean ATI_texture_env_combine3; + GLboolean ATI_fragment_shader; + GLboolean ATI_separate_stencil; + GLboolean IBM_rasterpos_clip; + GLboolean IBM_multimode_draw_arrays; + GLboolean MESA_pack_invert; + GLboolean MESA_resize_buffers; + GLboolean MESA_ycbcr_texture; + GLboolean MESA_texture_array; + GLboolean MESA_texture_signed_rgba; + GLboolean NV_blend_square; + GLboolean NV_conditional_render; + GLboolean NV_fragment_program; + GLboolean NV_fragment_program_option; + GLboolean NV_light_max_exponent; + GLboolean NV_point_sprite; + GLboolean NV_primitive_restart; + GLboolean NV_texgen_reflection; + GLboolean NV_texture_env_combine4; + GLboolean NV_texture_rectangle; + GLboolean NV_vertex_program; + GLboolean NV_vertex_program1_1; + GLboolean OES_read_format; + GLboolean SGI_texture_color_table; + GLboolean SGIS_generate_mipmap; + GLboolean SGIS_texture_edge_clamp; + GLboolean SGIS_texture_lod; + GLboolean TDFX_texture_compression_FXT1; + GLboolean S3_s3tc; + GLboolean OES_EGL_image; + GLboolean OES_draw_texture; + GLboolean EXT_texture_format_BGRA8888; + GLboolean extension_sentinel; + /** The extension string */ + const GLubyte *String; + /** Number of supported extensions */ + GLuint Count; +}; + + +/** + * A stack of matrices (projection, modelview, color, texture, etc). + */ +struct gl_matrix_stack +{ + GLmatrix *Top; /**< points into Stack */ + GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */ + GLuint Depth; /**< 0 <= Depth < MaxDepth */ + GLuint MaxDepth; /**< size of Stack[] array */ + GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */ +}; + + +/** + * \name Bits for image transfer operations + * \sa __struct gl_contextRec::ImageTransferState. + */ +/*@{*/ +#define IMAGE_SCALE_BIAS_BIT 0x1 +#define IMAGE_SHIFT_OFFSET_BIT 0x2 +#define IMAGE_MAP_COLOR_BIT 0x4 +#define IMAGE_CLAMP_BIT 0x800 + + +/** Pixel Transfer ops */ +#define IMAGE_BITS (IMAGE_SCALE_BIAS_BIT | \ + IMAGE_SHIFT_OFFSET_BIT | \ + IMAGE_MAP_COLOR_BIT) + +/** + * \name Bits to indicate what state has changed. + * + * 4 unused flags. + */ +/*@{*/ +#define _NEW_MODELVIEW 0x1 /**< __struct gl_contextRec::ModelView */ +#define _NEW_PROJECTION 0x2 /**< __struct gl_contextRec::Projection */ +#define _NEW_TEXTURE_MATRIX 0x4 /**< __struct gl_contextRec::TextureMatrix */ +#define _NEW_ACCUM 0x10 /**< __struct gl_contextRec::Accum */ +#define _NEW_COLOR 0x20 /**< __struct gl_contextRec::Color */ +#define _NEW_DEPTH 0x40 /**< __struct gl_contextRec::Depth */ +#define _NEW_EVAL 0x80 /**< __struct gl_contextRec::Eval, __struct gl_contextRec::EvalMap */ +#define _NEW_FOG 0x100 /**< __struct gl_contextRec::Fog */ +#define _NEW_HINT 0x200 /**< __struct gl_contextRec::Hint */ +#define _NEW_LIGHT 0x400 /**< __struct gl_contextRec::Light */ +#define _NEW_LINE 0x800 /**< __struct gl_contextRec::Line */ +#define _NEW_PIXEL 0x1000 /**< __struct gl_contextRec::Pixel */ +#define _NEW_POINT 0x2000 /**< __struct gl_contextRec::Point */ +#define _NEW_POLYGON 0x4000 /**< __struct gl_contextRec::Polygon */ +#define _NEW_POLYGONSTIPPLE 0x8000 /**< __struct gl_contextRec::PolygonStipple */ +#define _NEW_SCISSOR 0x10000 /**< __struct gl_contextRec::Scissor */ +#define _NEW_STENCIL 0x20000 /**< __struct gl_contextRec::Stencil */ +#define _NEW_TEXTURE 0x40000 /**< __struct gl_contextRec::Texture */ +#define _NEW_TRANSFORM 0x80000 /**< __struct gl_contextRec::Transform */ +#define _NEW_VIEWPORT 0x100000 /**< __struct gl_contextRec::Viewport */ +#define _NEW_PACKUNPACK 0x200000 /**< __struct gl_contextRec::Pack, __struct gl_contextRec::Unpack */ +#define _NEW_ARRAY 0x400000 /**< __struct gl_contextRec::Array */ +#define _NEW_RENDERMODE 0x800000 /**< __struct gl_contextRec::RenderMode, __struct gl_contextRec::Feedback, __struct gl_contextRec::Select */ +#define _NEW_BUFFERS 0x1000000 /**< __struct gl_contextRec::Visual, __struct gl_contextRec::DrawBuffer, */ +#define _NEW_MULTISAMPLE 0x2000000 /**< __struct gl_contextRec::Multisample */ +#define _NEW_TRACK_MATRIX 0x4000000 /**< __struct gl_contextRec::VertexProgram */ +#define _NEW_PROGRAM 0x8000000 /**< __struct gl_contextRec::VertexProgram */ +#define _NEW_CURRENT_ATTRIB 0x10000000 /**< __struct gl_contextRec::Current */ +#define _NEW_PROGRAM_CONSTANTS 0x20000000 +#define _NEW_BUFFER_OBJECT 0x40000000 +#define _NEW_ALL ~0 +/*@}*/ + + +/** + * \name Bits to track array state changes + * + * Also used to summarize array enabled. + */ +/*@{*/ +#define _NEW_ARRAY_VERTEX VERT_BIT_POS +#define _NEW_ARRAY_WEIGHT VERT_BIT_WEIGHT +#define _NEW_ARRAY_NORMAL VERT_BIT_NORMAL +#define _NEW_ARRAY_COLOR0 VERT_BIT_COLOR0 +#define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1 +#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG +#define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX +#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG +#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */ +#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0 +#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1 +#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2 +#define _NEW_ARRAY_TEXCOORD_3 VERT_BIT_TEX3 +#define _NEW_ARRAY_TEXCOORD_4 VERT_BIT_TEX4 +#define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5 +#define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6 +#define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7 +#define _NEW_ARRAY_ATTRIB_0 VERT_BIT_GENERIC0 /* start at bit 16 */ +#define _NEW_ARRAY_ALL 0xffffffff + + +#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i)) +#define _NEW_ARRAY_ATTRIB(i) (_NEW_ARRAY_ATTRIB_0 << (i)) +/*@}*/ + + + +/** + * \name A bunch of flags that we think might be useful to drivers. + * + * Set in the __struct gl_contextRec::_TriangleCaps bitfield. + */ +/*@{*/ +#define DD_FLATSHADE 0x1 +#define DD_SEPARATE_SPECULAR 0x2 +#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */ +#define DD_TRI_LIGHT_TWOSIDE 0x8 +#define DD_TRI_UNFILLED 0x10 +#define DD_TRI_SMOOTH 0x20 +#define DD_TRI_STIPPLE 0x40 +#define DD_TRI_OFFSET 0x80 +#define DD_LINE_SMOOTH 0x100 +#define DD_LINE_STIPPLE 0x200 +#define DD_POINT_SMOOTH 0x400 +#define DD_POINT_ATTEN 0x800 +#define DD_TRI_TWOSTENCIL 0x1000 +/*@}*/ + + +/** + * \name Define the state changes under which each of these bits might change + */ +/*@{*/ +#define _DD_NEW_FLATSHADE _NEW_LIGHT +#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG | _NEW_PROGRAM) +#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON +#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT +#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON +#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON +#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON +#define _DD_NEW_TRI_OFFSET _NEW_POLYGON +#define _DD_NEW_LINE_SMOOTH _NEW_LINE +#define _DD_NEW_LINE_STIPPLE _NEW_LINE +#define _DD_NEW_LINE_WIDTH _NEW_LINE +#define _DD_NEW_POINT_SMOOTH _NEW_POINT +#define _DD_NEW_POINT_SIZE _NEW_POINT +#define _DD_NEW_POINT_ATTEN _NEW_POINT +/*@}*/ + + +/** + * Composite state flags + */ +/*@{*/ +#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \ + _NEW_TEXTURE | \ + _NEW_POINT | \ + _NEW_PROGRAM | \ + _NEW_MODELVIEW) + +#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \ + _NEW_TEXTURE) + +#define _MESA_NEW_TRANSFER_STATE (_NEW_PIXEL) +/*@}*/ + + + + +/* This has to be included here. */ +#include "dd.h" + + +/** + * Display list flags. + * Strictly this is a tnl-private concept, but it doesn't seem + * worthwhile adding a tnl private structure just to hold this one bit + * of information: + */ +#define DLIST_DANGLING_REFS 0x1 + + +/** Opaque declaration of display list payload data type */ +union gl_dlist_node; + + +/** + * Provide a location where information about a display list can be + * collected. Could be extended with driverPrivate structures, + * etc. in the future. + */ +struct gl_display_list +{ + GLuint Name; + GLbitfield Flags; /**< DLIST_x flags */ + /** The dlist commands are in a linked list of nodes */ + union gl_dlist_node *Head; +}; + + +/** + * State used during display list compilation and execution. + */ +struct gl_dlist_state +{ + GLuint CallDepth; /**< Current recursion calling depth */ + + struct gl_display_list *CurrentList; /**< List currently being compiled */ + union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */ + GLuint CurrentPos; /**< Index into current block of nodes */ + + GLvertexformat ListVtxfmt; + + GLubyte ActiveAttribSize[VERT_ATTRIB_MAX]; + GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4]; + + GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX]; + GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4]; + + GLubyte ActiveIndex; + GLfloat CurrentIndex; + + GLubyte ActiveEdgeFlag; + GLboolean CurrentEdgeFlag; + + struct { + /* State known to have been set by the currently-compiling display + * list. Used to eliminate some redundant state changes. + */ + GLenum ShadeModel; + } Current; +}; + +/** + * Enum for the OpenGL APIs we know about and may support. + */ +typedef enum { + API_OPENGL, + API_OPENGLES, + API_OPENGLES2 +} gl_api; + +/** + * Mesa rendering context. + * + * This is the central context data structure for Mesa. Almost all + * OpenGL state is contained in this structure. + * Think of this as a base class from which device drivers will derive + * sub classes. + * + * The struct gl_context typedef names this structure. + */ +struct gl_context +{ + /** State possibly shared with other contexts in the address space */ + struct gl_shared_state *Shared; + + /** \name API function pointer tables */ + /*@{*/ + gl_api API; + struct _glapi_table *Save; /**< Display list save functions */ + struct _glapi_table *Exec; /**< Execute functions */ + struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */ + /*@}*/ + + struct gl_config Visual; + struct gl_framebuffer *DrawBuffer; /**< buffer for writing */ + struct gl_framebuffer *ReadBuffer; /**< buffer for reading */ + struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */ + struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */ + + /** + * Device driver function pointer table + */ + struct dd_function_table Driver; + + void *DriverCtx; /**< Points to device driver context/state */ + + /** Core/Driver constants */ + struct gl_constants Const; + + /** \name The various 4x4 matrix stacks */ + /*@{*/ + struct gl_matrix_stack ModelviewMatrixStack; + struct gl_matrix_stack ProjectionMatrixStack; + struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS]; + struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES]; + struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */ + /*@}*/ + + /** Combined modelview and projection matrix */ + GLmatrix _ModelProjectMatrix; + + /** \name Display lists */ + struct gl_dlist_state ListState; + + GLboolean ExecuteFlag; /**< Execute GL commands? */ + GLboolean CompileFlag; /**< Compile GL commands into display list? */ + + /** Extension information */ + struct gl_extensions Extensions; + + /** Version info */ + GLuint VersionMajor, VersionMinor; + char *VersionString; + + /** \name State attribute stack (for glPush/PopAttrib) */ + /*@{*/ + GLuint AttribStackDepth; + struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH]; + /*@}*/ + + /** \name Renderer attribute groups + * + * We define a struct for each attribute group to make pushing and popping + * attributes easy. Also it's a good organization. + */ + /*@{*/ + struct gl_accum_attrib Accum; /**< Accum buffer attributes */ + struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */ + struct gl_current_attrib Current; /**< Current attributes */ + struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */ + struct gl_eval_attrib Eval; /**< Eval attributes */ + struct gl_fog_attrib Fog; /**< Fog attributes */ + struct gl_hint_attrib Hint; /**< Hint attributes */ + struct gl_light_attrib Light; /**< Light attributes */ + struct gl_line_attrib Line; /**< Line attributes */ + struct gl_list_attrib List; /**< List attributes */ + struct gl_multisample_attrib Multisample; + struct gl_pixel_attrib Pixel; /**< Pixel attributes */ + struct gl_point_attrib Point; /**< Point attributes */ + struct gl_polygon_attrib Polygon; /**< Polygon attributes */ + GLuint PolygonStipple[32]; /**< Polygon stipple */ + struct gl_scissor_attrib Scissor; /**< Scissor attributes */ + struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */ + struct gl_texture_attrib Texture; /**< Texture attributes */ + struct gl_transform_attrib Transform; /**< Transformation attributes */ + struct gl_viewport_attrib Viewport; /**< Viewport attributes */ + /*@}*/ + + /** \name Client attribute stack */ + /*@{*/ + GLuint ClientAttribStackDepth; + struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH]; + /*@}*/ + + /** \name Client attribute groups */ + /*@{*/ + struct gl_array_attrib Array; /**< Vertex arrays */ + struct gl_pixelstore_attrib Pack; /**< Pixel packing */ + struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */ + struct gl_pixelstore_attrib DefaultPacking; /**< Default params */ + /*@}*/ + + /** \name Other assorted state (not pushed/popped on attribute stack) */ + /*@{*/ + struct gl_pixelmaps PixelMaps; + + struct gl_evaluators EvalMap; /**< All evaluators */ + struct gl_feedback Feedback; /**< Feedback */ + struct gl_selection Select; /**< Selection */ + + struct gl_program_state Program; /**< general program state */ + struct gl_vertex_program_state VertexProgram; + struct gl_fragment_program_state FragmentProgram; + struct gl_geometry_program_state GeometryProgram; + struct gl_ati_fragment_shader_state ATIFragmentShader; + + struct gl_shader_state Shader; /**< GLSL shader object state */ + struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES]; + + struct gl_query_state Query; /**< occlusion, timer queries */ + + struct gl_transform_feedback TransformFeedback; + + struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */ + struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */ + /*@}*/ + + struct gl_meta_state *Meta; /**< for "meta" operations */ + + /* GL_EXT_framebuffer_object */ + struct gl_renderbuffer *CurrentRenderbuffer; + + GLenum ErrorValue; /**< Last error code */ + + /** + * Recognize and silence repeated error debug messages in buggy apps. + */ + const char *ErrorDebugFmtString; + GLuint ErrorDebugCount; + + GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ + GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ + + GLboolean ViewportInitialized; /**< has viewport size been initialized? */ + + GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */ + + /** \name Derived state */ + /*@{*/ + /** Bitwise-or of DD_* flags. Note that this bitfield may be used before + * state validation so they need to always be current. + */ + GLbitfield _TriangleCaps; + GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */ + GLfloat _EyeZDir[3]; + GLfloat _ModelViewInvScale; + GLboolean _NeedEyeCoords; + GLboolean _ForceEyeCoords; + + GLuint TextureStateTimestamp; /**< detect changes to shared state */ + + struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */ + struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ + /**@}*/ + + struct gl_list_extensions *ListExt; /**< driver dlist extensions */ + + /** \name For debugging/development only */ + /*@{*/ + GLboolean FirstTimeCurrent; + /*@}*/ + + /** Dither disable via MESA_NO_DITHER env var */ + GLboolean NoDither; + + /** software compression/decompression supported or not */ + GLboolean Mesa_DXTn; + + GLboolean TextureFormatSupported[MESA_FORMAT_COUNT]; + + /** + * Use dp4 (rather than mul/mad) instructions for position + * transformation? + */ + GLboolean mvp_with_dp4; + + /** + * \name Hooks for module contexts. + * + * These will eventually live in the driver or elsewhere. + */ + /*@{*/ + void *swrast_context; + void *swsetup_context; + void *swtnl_context; + void *swtnl_im; + struct st_context *st; + void *aelt_context; + /*@}*/ +}; + + +/** The string names for GL_POINT, GL_LINE_LOOP, etc */ +extern const char *_mesa_prim_name[GL_POLYGON+4]; + + +#ifdef DEBUG +extern int MESA_VERBOSE; +extern int MESA_DEBUG_FLAGS; +# define MESA_FUNCTION __FUNCTION__ +#else +# define MESA_VERBOSE 0 +# define MESA_DEBUG_FLAGS 0 +# define MESA_FUNCTION "a function" +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + + +/** The MESA_VERBOSE var is a bitmask of these flags */ +enum _verbose +{ + VERBOSE_VARRAY = 0x0001, + VERBOSE_TEXTURE = 0x0002, + VERBOSE_MATERIAL = 0x0004, + VERBOSE_PIPELINE = 0x0008, + VERBOSE_DRIVER = 0x0010, + VERBOSE_STATE = 0x0020, + VERBOSE_API = 0x0040, + VERBOSE_DISPLAY_LIST = 0x0100, + VERBOSE_LIGHTING = 0x0200, + VERBOSE_PRIMS = 0x0400, + VERBOSE_VERTS = 0x0800, + VERBOSE_DISASSEM = 0x1000, + VERBOSE_DRAW = 0x2000, + VERBOSE_SWAPBUFFERS = 0x4000 +}; + + +/** The MESA_DEBUG_FLAGS var is a bitmask of these flags */ +enum _debug +{ + DEBUG_ALWAYS_FLUSH = 0x1 +}; + + + +#endif /* MTYPES_H */ diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 2b5b65805..e83117523 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -1,1891 +1,1930 @@ -/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file shaderapi.c
- * \author Brian Paul
- *
- * Implementation of GLSL-related API functions.
- * The glUniform* functions are in uniforms.c
- *
- *
- * XXX things to do:
- * 1. Check that the right error code is generated for all _mesa_error() calls.
- * 2. Insert FLUSH_VERTICES calls in various places
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/dispatch.h"
-#include "main/enums.h"
-#include "main/hash.h"
-#include "main/mfeatures.h"
-#include "main/mtypes.h"
-#include "main/shaderapi.h"
-#include "main/shaderobj.h"
-#include "program/program.h"
-#include "program/prog_parameter.h"
-#include "program/prog_uniform.h"
-#include "talloc.h"
-#include <stdbool.h>
-#include "../glsl/glsl_parser_extras.h"
-
-/** Define this to enable shader substitution (see below) */
-#define SHADER_SUBST 0
-
-
-/**
- * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
- */
-static GLbitfield
-get_shader_flags(void)
-{
- GLbitfield flags = 0x0;
- const char *env = _mesa_getenv("MESA_GLSL");
-
- if (env) {
- if (strstr(env, "dump"))
- flags |= GLSL_DUMP;
- if (strstr(env, "log"))
- flags |= GLSL_LOG;
- if (strstr(env, "nopvert"))
- flags |= GLSL_NOP_VERT;
- if (strstr(env, "nopfrag"))
- flags |= GLSL_NOP_FRAG;
- if (strstr(env, "nopt"))
- flags |= GLSL_NO_OPT;
- else if (strstr(env, "opt"))
- flags |= GLSL_OPT;
- if (strstr(env, "uniform"))
- flags |= GLSL_UNIFORMS;
- if (strstr(env, "useprog"))
- flags |= GLSL_USE_PROG;
- }
-
- return flags;
-}
-
-
-/**
- * Initialize context's shader state.
- */
-void
-_mesa_init_shader_state(struct gl_context *ctx)
-{
- /* Device drivers may override these to control what kind of instructions
- * are generated by the GLSL compiler.
- */
- struct gl_shader_compiler_options options;
- gl_shader_type sh;
-
- memset(&options, 0, sizeof(options));
- options.MaxUnrollIterations = 32;
-
- /* Default pragma settings */
- options.DefaultPragmas.Optimize = GL_TRUE;
-
- for (sh = 0; sh < MESA_SHADER_TYPES; ++sh)
- memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
-
- ctx->Shader.Flags = get_shader_flags();
-}
-
-
-/**
- * Free the per-context shader-related state.
- */
-void
-_mesa_free_shader_state(struct gl_context *ctx)
-{
- _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentVertexProgram, NULL);
- _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentGeometryProgram,
- NULL);
- _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
- NULL);
- _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
-}
-
-
-/**
- * Return the size of the given GLSL datatype, in floats (components).
- */
-GLint
-_mesa_sizeof_glsl_type(GLenum type)
-{
- switch (type) {
- case GL_FLOAT:
- case GL_INT:
- case GL_BOOL:
- case GL_SAMPLER_1D:
- case GL_SAMPLER_2D:
- case GL_SAMPLER_3D:
- case GL_SAMPLER_CUBE:
- case GL_SAMPLER_1D_SHADOW:
- case GL_SAMPLER_2D_SHADOW:
- case GL_SAMPLER_2D_RECT_ARB:
- case GL_SAMPLER_2D_RECT_SHADOW_ARB:
- case GL_SAMPLER_1D_ARRAY_EXT:
- case GL_SAMPLER_2D_ARRAY_EXT:
- case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
- case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
- case GL_SAMPLER_CUBE_SHADOW_EXT:
- return 1;
- case GL_FLOAT_VEC2:
- case GL_INT_VEC2:
- case GL_UNSIGNED_INT_VEC2:
- case GL_BOOL_VEC2:
- return 2;
- case GL_FLOAT_VEC3:
- case GL_INT_VEC3:
- case GL_UNSIGNED_INT_VEC3:
- case GL_BOOL_VEC3:
- return 3;
- case GL_FLOAT_VEC4:
- case GL_INT_VEC4:
- case GL_UNSIGNED_INT_VEC4:
- case GL_BOOL_VEC4:
- return 4;
- case GL_FLOAT_MAT2:
- case GL_FLOAT_MAT2x3:
- case GL_FLOAT_MAT2x4:
- return 8; /* two float[4] vectors */
- case GL_FLOAT_MAT3:
- case GL_FLOAT_MAT3x2:
- case GL_FLOAT_MAT3x4:
- return 12; /* three float[4] vectors */
- case GL_FLOAT_MAT4:
- case GL_FLOAT_MAT4x2:
- case GL_FLOAT_MAT4x3:
- return 16; /* four float[4] vectors */
- default:
- _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()");
- return 1;
- }
-}
-
-
-/**
- * Copy string from <src> to <dst>, up to maxLength characters, returning
- * length of <dst> in <length>.
- * \param src the strings source
- * \param maxLength max chars to copy
- * \param length returns number of chars copied
- * \param dst the string destination
- */
-void
-_mesa_copy_string(GLchar *dst, GLsizei maxLength,
- GLsizei *length, const GLchar *src)
-{
- GLsizei len;
- for (len = 0; len < maxLength - 1 && src && src[len]; len++)
- dst[len] = src[len];
- if (maxLength > 0)
- dst[len] = 0;
- if (length)
- *length = len;
-}
-
-
-
-/**
- * Confirm that the a shader type is valid and supported by the implementation
- *
- * \param ctx Current GL context
- * \param type Shader target
- *
- */
-static bool
-validate_shader_target(const struct gl_context *ctx, GLenum type)
-{
- switch (type) {
-#if FEATURE_ARB_fragment_shader
- case GL_FRAGMENT_SHADER:
- return ctx->Extensions.ARB_fragment_shader;
-#endif
-#if FEATURE_ARB_vertex_shader
- case GL_VERTEX_SHADER:
- return ctx->Extensions.ARB_vertex_shader;
-#endif
-#if FEATURE_ARB_geometry_shader4
- case GL_GEOMETRY_SHADER_ARB:
- return ctx->Extensions.ARB_geometry_shader4;
-#endif
- default:
- return false;
- }
-}
-
-
-/**
- * Find the length of the longest transform feedback varying name
- * which was specified with glTransformFeedbackVaryings().
- */
-static GLint
-longest_feedback_varying_name(const struct gl_shader_program *shProg)
-{
- GLuint i;
- GLint max = 0;
- for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
- GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
- if (len > max)
- max = len;
- }
- return max;
-}
-
-
-
-static GLboolean
-is_program(struct gl_context *ctx, GLuint name)
-{
- struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
- return shProg ? GL_TRUE : GL_FALSE;
-}
-
-
-static GLboolean
-is_shader(struct gl_context *ctx, GLuint name)
-{
- struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
- return shader ? GL_TRUE : GL_FALSE;
-}
-
-
-/**
- * Attach shader to a shader program.
- */
-static void
-attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
-{
- struct gl_shader_program *shProg;
- struct gl_shader *sh;
- GLuint i, n;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
- if (!shProg)
- return;
-
- sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
- if (!sh) {
- return;
- }
-
- n = shProg->NumShaders;
- for (i = 0; i < n; i++) {
- if (shProg->Shaders[i] == sh) {
- /* The shader is already attched to this program. The
- * GL_ARB_shader_objects spec says:
- *
- * "The error INVALID_OPERATION is generated by AttachObjectARB
- * if <obj> is already attached to <containerObj>."
- */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
- return;
- }
- }
-
- /* grow list */
- shProg->Shaders = (struct gl_shader **)
- _mesa_realloc(shProg->Shaders,
- n * sizeof(struct gl_shader *),
- (n + 1) * sizeof(struct gl_shader *));
- if (!shProg->Shaders) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
- return;
- }
-
- /* append */
- shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
- _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
- shProg->NumShaders++;
-}
-
-
-static GLint
-get_attrib_location(struct gl_context *ctx, GLuint program, const GLchar *name)
-{
- struct gl_shader_program *shProg
- = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
-
- if (!shProg) {
- return -1;
- }
-
- if (!shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetAttribLocation(program not linked)");
- return -1;
- }
-
- if (!name)
- return -1;
-
- if (shProg->VertexProgram) {
- const struct gl_program_parameter_list *attribs =
- shProg->VertexProgram->Base.Attributes;
- if (attribs) {
- GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
- if (i >= 0) {
- return attribs->Parameters[i].StateIndexes[0];
- }
- }
- }
- return -1;
-}
-
-
-static void
-bind_attrib_location(struct gl_context *ctx, GLuint program, GLuint index,
- const GLchar *name)
-{
- struct gl_shader_program *shProg;
- const GLint size = -1; /* unknown size */
- GLint i, oldIndex;
- GLenum datatype = GL_FLOAT_VEC4;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program,
- "glBindAttribLocation");
- if (!shProg) {
- return;
- }
-
- if (!name)
- return;
-
- if (strncmp(name, "gl_", 3) == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindAttribLocation(illegal name)");
- return;
- }
-
- if (index >= ctx->Const.VertexProgram.MaxAttribs) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
- return;
- }
-
- if (shProg->LinkStatus) {
- /* get current index/location for the attribute */
- oldIndex = get_attrib_location(ctx, program, name);
- }
- else {
- oldIndex = -1;
- }
-
- /* this will replace the current value if it's already in the list */
- i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
- if (i < 0) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
- return;
- }
-
- /*
- * Note that this attribute binding won't go into effect until
- * glLinkProgram is called again.
- */
-}
-
-
-static void
-bind_frag_data_location(struct gl_context *ctx, GLuint program,
- GLuint colorNumber, const GLchar *name)
-{
- _mesa_problem(ctx, "bind_frag_data_location() not implemented yet");
-}
-
-
-static GLuint
-create_shader(struct gl_context *ctx, GLenum type)
-{
- struct gl_shader *sh;
- GLuint name;
-
- if (!validate_shader_target(ctx, type)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
- return 0;
- }
-
- name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
- sh = ctx->Driver.NewShader(ctx, name, type);
- _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
-
- return name;
-}
-
-
-static GLuint
-create_shader_program(struct gl_context *ctx)
-{
- GLuint name;
- struct gl_shader_program *shProg;
-
- name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
-
- shProg = ctx->Driver.NewShaderProgram(ctx, name);
-
- _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
-
- assert(shProg->RefCount == 1);
-
- return name;
-}
-
-
-/**
- * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
- * DeleteProgramARB.
- */
-static void
-delete_shader_program(struct gl_context *ctx, GLuint name)
-{
- /*
- * NOTE: deleting shaders/programs works a bit differently than
- * texture objects (and buffer objects, etc). Shader/program
- * handles/IDs exist in the hash table until the object is really
- * deleted (refcount==0). With texture objects, the handle/ID is
- * removed from the hash table in glDeleteTextures() while the tex
- * object itself might linger until its refcount goes to zero.
- */
- struct gl_shader_program *shProg;
-
- shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
- if (!shProg)
- return;
-
- shProg->DeletePending = GL_TRUE;
-
- /* effectively, decr shProg's refcount */
- _mesa_reference_shader_program(ctx, &shProg, NULL);
-}
-
-
-static void
-delete_shader(struct gl_context *ctx, GLuint shader)
-{
- struct gl_shader *sh;
-
- sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
- if (!sh)
- return;
-
- sh->DeletePending = GL_TRUE;
-
- /* effectively, decr sh's refcount */
- _mesa_reference_shader(ctx, &sh, NULL);
-}
-
-
-static void
-detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
-{
- struct gl_shader_program *shProg;
- GLuint n;
- GLuint i, j;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
- if (!shProg)
- return;
-
- n = shProg->NumShaders;
-
- for (i = 0; i < n; i++) {
- if (shProg->Shaders[i]->Name == shader) {
- /* found it */
- struct gl_shader **newList;
-
- /* release */
- _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
-
- /* alloc new, smaller array */
- newList = (struct gl_shader **)
- malloc((n - 1) * sizeof(struct gl_shader *));
- if (!newList) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
- return;
- }
- for (j = 0; j < i; j++) {
- newList[j] = shProg->Shaders[j];
- }
- while (++i < n)
- newList[j++] = shProg->Shaders[i];
- free(shProg->Shaders);
-
- shProg->Shaders = newList;
- shProg->NumShaders = n - 1;
-
-#ifdef DEBUG
- /* sanity check */
- {
- for (j = 0; j < shProg->NumShaders; j++) {
- assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
- shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
- assert(shProg->Shaders[j]->RefCount > 0);
- }
- }
-#endif
-
- return;
- }
- }
-
- /* not found */
- {
- GLenum err;
- if (is_shader(ctx, shader))
- err = GL_INVALID_OPERATION;
- else if (is_program(ctx, shader))
- err = GL_INVALID_OPERATION;
- else
- err = GL_INVALID_VALUE;
- _mesa_error(ctx, err, "glDetachProgram(shader)");
- return;
- }
-}
-
-
-static void
-get_active_attrib(struct gl_context *ctx, GLuint program, GLuint index,
- GLsizei maxLength, GLsizei *length, GLint *size,
- GLenum *type, GLchar *nameOut)
-{
- const struct gl_program_parameter_list *attribs = NULL;
- struct gl_shader_program *shProg;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
- if (!shProg)
- return;
-
- if (shProg->VertexProgram)
- attribs = shProg->VertexProgram->Base.Attributes;
-
- if (!attribs || index >= attribs->NumParameters) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
- return;
- }
-
- _mesa_copy_string(nameOut, maxLength, length,
- attribs->Parameters[index].Name);
-
- if (size)
- *size = attribs->Parameters[index].Size
- / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType);
-
- if (type)
- *type = attribs->Parameters[index].DataType;
-}
-
-
-/**
- * Return list of shaders attached to shader program.
- */
-static void
-get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
- GLsizei *count, GLuint *obj)
-{
- struct gl_shader_program *shProg =
- _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
- if (shProg) {
- GLuint i;
- for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
- obj[i] = shProg->Shaders[i]->Name;
- }
- if (count)
- *count = i;
- }
-}
-
-
-static GLint
-get_frag_data_location(struct gl_context *ctx, GLuint program,
- const GLchar *name)
-{
- _mesa_problem(ctx, "get_frag_data_location() not implemented yet");
- return -1;
-}
-
-
-
-/**
- * glGetHandleARB() - return ID/name of currently bound shader program.
- */
-static GLuint
-get_handle(struct gl_context *ctx, GLenum pname)
-{
- if (pname == GL_PROGRAM_OBJECT_ARB) {
- if (ctx->Shader.ActiveProgram)
- return ctx->Shader.ActiveProgram->Name;
- else
- return 0;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
- return 0;
- }
-}
-
-
-/**
- * glGetProgramiv() - get shader program state.
- * Note that this is for GLSL shader programs, not ARB vertex/fragment
- * programs (see glGetProgramivARB).
- */
-static void
-get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params)
-{
- const struct gl_program_parameter_list *attribs;
- struct gl_shader_program *shProg
- = _mesa_lookup_shader_program(ctx, program);
-
- if (!shProg) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
- return;
- }
-
- if (shProg->VertexProgram)
- attribs = shProg->VertexProgram->Base.Attributes;
- else
- attribs = NULL;
-
- switch (pname) {
- case GL_DELETE_STATUS:
- *params = shProg->DeletePending;
- break;
- case GL_LINK_STATUS:
- *params = shProg->LinkStatus;
- break;
- case GL_VALIDATE_STATUS:
- *params = shProg->Validated;
- break;
- case GL_INFO_LOG_LENGTH:
- *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
- break;
- case GL_ATTACHED_SHADERS:
- *params = shProg->NumShaders;
- break;
- case GL_ACTIVE_ATTRIBUTES:
- *params = attribs ? attribs->NumParameters : 0;
- break;
- case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
- *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
- break;
- case GL_ACTIVE_UNIFORMS:
- *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
- break;
- case GL_ACTIVE_UNIFORM_MAX_LENGTH:
- *params = _mesa_longest_uniform_name(shProg->Uniforms);
- if (*params > 0)
- (*params)++; /* add one for terminating zero */
- break;
- case GL_PROGRAM_BINARY_LENGTH_OES:
- *params = 0;
- break;
-#if FEATURE_EXT_transform_feedback
- case GL_TRANSFORM_FEEDBACK_VARYINGS:
- *params = shProg->TransformFeedback.NumVarying;
- break;
- case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
- *params = longest_feedback_varying_name(shProg) + 1;
- break;
- case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
- *params = shProg->TransformFeedback.BufferMode;
- break;
-#endif
-#if FEATURE_ARB_geometry_shader4
- case GL_GEOMETRY_VERTICES_OUT_ARB:
- *params = shProg->Geom.VerticesOut;
- break;
- case GL_GEOMETRY_INPUT_TYPE_ARB:
- *params = shProg->Geom.InputType;
- break;
- case GL_GEOMETRY_OUTPUT_TYPE_ARB:
- *params = shProg->Geom.OutputType;
- break;
-#endif
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
- return;
- }
-}
-
-
-/**
- * glGetShaderiv() - get GLSL shader state
- */
-static void
-get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
-{
- struct gl_shader *shader =
- _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
-
- if (!shader) {
- return;
- }
-
- switch (pname) {
- case GL_SHADER_TYPE:
- *params = shader->Type;
- break;
- case GL_DELETE_STATUS:
- *params = shader->DeletePending;
- break;
- case GL_COMPILE_STATUS:
- *params = shader->CompileStatus;
- break;
- case GL_INFO_LOG_LENGTH:
- *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
- break;
- case GL_SHADER_SOURCE_LENGTH:
- *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
- return;
- }
-}
-
-
-static void
-get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
- GLsizei *length, GLchar *infoLog)
-{
- struct gl_shader_program *shProg
- = _mesa_lookup_shader_program(ctx, program);
- if (!shProg) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
- return;
- }
- _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
-}
-
-
-static void
-get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
- GLsizei *length, GLchar *infoLog)
-{
- struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
- if (!sh) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
- return;
- }
- _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
-}
-
-
-/**
- * Return shader source code.
- */
-static void
-get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
- GLsizei *length, GLchar *sourceOut)
-{
- struct gl_shader *sh;
- sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
- if (!sh) {
- return;
- }
- _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
-}
-
-
-/**
- * Set/replace shader source code.
- */
-static void
-shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
-{
- struct gl_shader *sh;
-
- sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
- if (!sh)
- return;
-
- /* free old shader source string and install new one */
- if (sh->Source) {
- free((void *) sh->Source);
- }
- sh->Source = source;
- sh->CompileStatus = GL_FALSE;
-#ifdef DEBUG
- sh->SourceChecksum = _mesa_str_checksum(sh->Source);
-#endif
-}
-
-
-/**
- * Compile a shader.
- */
-static void
-compile_shader(struct gl_context *ctx, GLuint shaderObj)
-{
- struct gl_shader *sh;
- struct gl_shader_compiler_options *options;
-
- sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
- if (!sh)
- return;
-
- options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)];
-
- /* set default pragma state for shader */
- sh->Pragmas = options->DefaultPragmas;
-
- /* this call will set the sh->CompileStatus field to indicate if
- * compilation was successful.
- */
- _mesa_glsl_compile_shader(ctx, sh);
-}
-
-
-/**
- * Link a program's shaders.
- */
-static void
-link_program(struct gl_context *ctx, GLuint program)
-{
- struct gl_shader_program *shProg;
- struct gl_transform_feedback_object *obj =
- ctx->TransformFeedback.CurrentObject;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
- if (!shProg)
- return;
-
- if (obj->Active
- && (shProg == ctx->Shader.CurrentVertexProgram
- || shProg == ctx->Shader.CurrentGeometryProgram
- || shProg == ctx->Shader.CurrentFragmentProgram)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLinkProgram(transform feedback active");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
- _mesa_glsl_link_shader(ctx, shProg);
-
- /* debug code */
- if (0) {
- GLuint i;
-
- printf("Link %u shaders in program %u: %s\n",
- shProg->NumShaders, shProg->Name,
- shProg->LinkStatus ? "Success" : "Failed");
-
- for (i = 0; i < shProg->NumShaders; i++) {
- printf(" shader %u, type 0x%x\n",
- shProg->Shaders[i]->Name,
- shProg->Shaders[i]->Type);
- }
- }
-}
-
-
-/**
- * Print basic shader info (for debug).
- */
-static void
-print_shader_info(const struct gl_shader_program *shProg)
-{
- GLuint i;
-
- printf("Mesa: glUseProgram(%u)\n", shProg->Name);
- for (i = 0; i < shProg->NumShaders; i++) {
- const char *s;
- switch (shProg->Shaders[i]->Type) {
- case GL_VERTEX_SHADER:
- s = "vertex";
- break;
- case GL_FRAGMENT_SHADER:
- s = "fragment";
- break;
- case GL_GEOMETRY_SHADER:
- s = "geometry";
- break;
- default:
- s = "";
- }
- printf(" %s shader %u, checksum %u\n", s,
- shProg->Shaders[i]->Name,
- shProg->Shaders[i]->SourceChecksum);
- }
- if (shProg->VertexProgram)
- printf(" vert prog %u\n", shProg->VertexProgram->Base.Id);
- if (shProg->FragmentProgram)
- printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id);
-}
-
-
-/**
- * Use the named shader program for subsequent glUniform calls
- */
-void
-_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
- const char *caller)
-{
- if ((shProg != NULL) && !shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(program %u not linked)", caller, shProg->Name);
- return;
- }
-
- if (ctx->Shader.ActiveProgram != shProg) {
- _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
- }
-}
-
-/**
- */
-static bool
-use_shader_program(struct gl_context *ctx, GLenum type,
- struct gl_shader_program *shProg)
-{
- struct gl_shader_program **target;
-
- switch (type) {
-#if FEATURE_ARB_vertex_shader
- case GL_VERTEX_SHADER:
- target = &ctx->Shader.CurrentVertexProgram;
- if ((shProg == NULL)
- || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) {
- shProg = NULL;
- }
- break;
-#endif
-#if FEATURE_ARB_geometry_shader4
- case GL_GEOMETRY_SHADER_ARB:
- target = &ctx->Shader.CurrentGeometryProgram;
- if ((shProg == NULL)
- || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) {
- shProg = NULL;
- }
- break;
-#endif
-#if FEATURE_ARB_fragment_shader
- case GL_FRAGMENT_SHADER:
- target = &ctx->Shader.CurrentFragmentProgram;
- if ((shProg == NULL)
- || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) {
- shProg = NULL;
- }
- break;
-#endif
- default:
- return false;
- }
-
- if (*target != shProg) {
- FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
- _mesa_reference_shader_program(ctx, target, shProg);
- return true;
- }
-
- return false;
-}
-
-/**
- * Use the named shader program for subsequent rendering.
- */
-void
-_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
-{
- use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
- use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg);
- use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg);
- _mesa_active_program(ctx, shProg, "glUseProgram");
-
- if (ctx->Driver.UseProgram)
- ctx->Driver.UseProgram(ctx, shProg);
-}
-
-
-/**
- * Validate a program's samplers.
- * Specifically, check that there aren't two samplers of different types
- * pointing to the same texture unit.
- * \return GL_TRUE if valid, GL_FALSE if invalid
- */
-static GLboolean
-validate_samplers(const struct gl_program *prog, char *errMsg)
-{
- static const char *targetName[] = {
- "TEXTURE_2D_ARRAY",
- "TEXTURE_1D_ARRAY",
- "TEXTURE_CUBE",
- "TEXTURE_3D",
- "TEXTURE_RECT",
- "TEXTURE_2D",
- "TEXTURE_1D",
- };
- GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
- GLbitfield samplersUsed = prog->SamplersUsed;
- GLuint i;
-
- assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
-
- if (samplersUsed == 0x0)
- return GL_TRUE;
-
- for (i = 0; i < Elements(targetUsed); i++)
- targetUsed[i] = -1;
-
- /* walk over bits which are set in 'samplers' */
- while (samplersUsed) {
- GLuint unit;
- gl_texture_index target;
- GLint sampler = _mesa_ffs(samplersUsed) - 1;
- assert(sampler >= 0);
- assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
- unit = prog->SamplerUnits[sampler];
- target = prog->SamplerTargets[sampler];
- if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) {
- _mesa_snprintf(errMsg, 100,
- "Texture unit %d is accessed both as %s and %s",
- unit, targetName[targetUsed[unit]], targetName[target]);
- return GL_FALSE;
- }
- targetUsed[unit] = target;
- samplersUsed ^= (1 << sampler);
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Do validation of the given shader program.
- * \param errMsg returns error message if validation fails.
- * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
- */
-static GLboolean
-validate_shader_program(const struct gl_shader_program *shProg,
- char *errMsg)
-{
- const struct gl_vertex_program *vp = shProg->VertexProgram;
- const struct gl_fragment_program *fp = shProg->FragmentProgram;
-
- if (!shProg->LinkStatus) {
- return GL_FALSE;
- }
-
- /* From the GL spec, a program is invalid if any of these are true:
-
- any two active samplers in the current program object are of
- different types, but refer to the same texture image unit,
-
- any active sampler in the current program object refers to a texture
- image unit where fixed-function fragment processing accesses a
- texture target that does not match the sampler type, or
-
- the sum of the number of active samplers in the program and the
- number of texture image units enabled for fixed-function fragment
- processing exceeds the combined limit on the total number of texture
- image units allowed.
- */
-
-
- /*
- * Check: any two active samplers in the current program object are of
- * different types, but refer to the same texture image unit,
- */
- if (vp && !validate_samplers(&vp->Base, errMsg)) {
- return GL_FALSE;
- }
- if (fp && !validate_samplers(&fp->Base, errMsg)) {
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Called via glValidateProgram()
- */
-static void
-validate_program(struct gl_context *ctx, GLuint program)
-{
- struct gl_shader_program *shProg;
- char errMsg[100];
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
- if (!shProg) {
- return;
- }
-
- shProg->Validated = validate_shader_program(shProg, errMsg);
- if (!shProg->Validated) {
- /* update info log */
- if (shProg->InfoLog) {
- talloc_free(shProg->InfoLog);
- }
- shProg->InfoLog = talloc_strdup(shProg, errMsg);
- }
-}
-
-
-
-void GLAPIENTRY
-_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
-{
- GET_CURRENT_CONTEXT(ctx);
- attach_shader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_AttachShader(GLuint program, GLuint shader)
-{
- GET_CURRENT_CONTEXT(ctx);
- attach_shader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
- const GLcharARB *name)
-{
- GET_CURRENT_CONTEXT(ctx);
- bind_attrib_location(ctx, program, index, name);
-}
-
-
-/* GL_EXT_gpu_shader4, GL3 */
-void GLAPIENTRY
-_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber,
- const GLchar *name)
-{
- GET_CURRENT_CONTEXT(ctx);
- bind_frag_data_location(ctx, program, colorNumber, name);
-}
-
-
-void GLAPIENTRY
-_mesa_CompileShaderARB(GLhandleARB shaderObj)
-{
- GET_CURRENT_CONTEXT(ctx);
- compile_shader(ctx, shaderObj);
-}
-
-
-GLuint GLAPIENTRY
-_mesa_CreateShader(GLenum type)
-{
- GET_CURRENT_CONTEXT(ctx);
- return create_shader(ctx, type);
-}
-
-
-GLhandleARB GLAPIENTRY
-_mesa_CreateShaderObjectARB(GLenum type)
-{
- GET_CURRENT_CONTEXT(ctx);
- return create_shader(ctx, type);
-}
-
-
-GLuint GLAPIENTRY
-_mesa_CreateProgram(void)
-{
- GET_CURRENT_CONTEXT(ctx);
- return create_shader_program(ctx);
-}
-
-
-GLhandleARB GLAPIENTRY
-_mesa_CreateProgramObjectARB(void)
-{
- GET_CURRENT_CONTEXT(ctx);
- return create_shader_program(ctx);
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteObjectARB(GLhandleARB obj)
-{
- if (obj) {
- GET_CURRENT_CONTEXT(ctx);
- if (is_program(ctx, obj)) {
- delete_shader_program(ctx, obj);
- }
- else if (is_shader(ctx, obj)) {
- delete_shader(ctx, obj);
- }
- else {
- /* error? */
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteProgram(GLuint name)
-{
- if (name) {
- GET_CURRENT_CONTEXT(ctx);
- delete_shader_program(ctx, name);
- }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteShader(GLuint name)
-{
- if (name) {
- GET_CURRENT_CONTEXT(ctx);
- delete_shader(ctx, name);
- }
-}
-
-
-void GLAPIENTRY
-_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
-{
- GET_CURRENT_CONTEXT(ctx);
- detach_shader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_DetachShader(GLuint program, GLuint shader)
-{
- GET_CURRENT_CONTEXT(ctx);
- detach_shader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
- GLsizei maxLength, GLsizei * length, GLint * size,
- GLenum * type, GLcharARB * name)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_active_attrib(ctx, program, index, maxLength, length, size, type, name);
-}
-
-
-void GLAPIENTRY
-_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
- GLsizei * count, GLhandleARB * obj)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_attached_shaders(ctx, container, maxCount, count, obj);
-}
-
-
-void GLAPIENTRY
-_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
- GLsizei *count, GLuint *obj)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_attached_shaders(ctx, program, maxCount, count, obj);
-}
-
-
-GLint GLAPIENTRY
-_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
-{
- GET_CURRENT_CONTEXT(ctx);
- return get_attrib_location(ctx, program, name);
-}
-
-
-/* GL_EXT_gpu_shader4, GL3 */
-GLint GLAPIENTRY
-_mesa_GetFragDataLocation(GLuint program, const GLchar *name)
-{
- GET_CURRENT_CONTEXT(ctx);
- return get_frag_data_location(ctx, program, name);
-}
-
-
-
-void GLAPIENTRY
-_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
- GLcharARB * infoLog)
-{
- GET_CURRENT_CONTEXT(ctx);
- if (is_program(ctx, object)) {
- get_program_info_log(ctx, object, maxLength, length, infoLog);
- }
- else if (is_shader(ctx, object)) {
- get_shader_info_log(ctx, object, maxLength, length, infoLog);
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
-{
- GET_CURRENT_CONTEXT(ctx);
- /* Implement in terms of GetProgramiv, GetShaderiv */
- if (is_program(ctx, object)) {
- if (pname == GL_OBJECT_TYPE_ARB) {
- *params = GL_PROGRAM_OBJECT_ARB;
- }
- else {
- get_programiv(ctx, object, pname, params);
- }
- }
- else if (is_shader(ctx, object)) {
- if (pname == GL_OBJECT_TYPE_ARB) {
- *params = GL_SHADER_OBJECT_ARB;
- }
- else {
- get_shaderiv(ctx, object, pname, params);
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
- GLfloat *params)
-{
- GLint iparams[1]; /* XXX is one element enough? */
- _mesa_GetObjectParameterivARB(object, pname, iparams);
- params[0] = (GLfloat) iparams[0];
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_programiv(ctx, program, pname, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_shaderiv(ctx, shader, pname, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
- GLsizei *length, GLchar *infoLog)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_program_info_log(ctx, program, bufSize, length, infoLog);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
- GLsizei *length, GLchar *infoLog)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_shader_info_log(ctx, shader, bufSize, length, infoLog);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
- GLsizei *length, GLcharARB *sourceOut)
-{
- GET_CURRENT_CONTEXT(ctx);
- get_shader_source(ctx, shader, maxLength, length, sourceOut);
-}
-
-
-GLhandleARB GLAPIENTRY
-_mesa_GetHandleARB(GLenum pname)
-{
- GET_CURRENT_CONTEXT(ctx);
- return get_handle(ctx, pname);
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsProgram(GLuint name)
-{
- GET_CURRENT_CONTEXT(ctx);
- return is_program(ctx, name);
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsShader(GLuint name)
-{
- GET_CURRENT_CONTEXT(ctx);
- return is_shader(ctx, name);
-}
-
-
-void GLAPIENTRY
-_mesa_LinkProgramARB(GLhandleARB programObj)
-{
- GET_CURRENT_CONTEXT(ctx);
- link_program(ctx, programObj);
-}
-
-
-
-/**
- * Read shader source code from a file.
- * Useful for debugging to override an app's shader.
- */
-static GLcharARB *
-read_shader(const char *fname)
-{
- const int max = 50*1000;
- FILE *f = fopen(fname, "r");
- GLcharARB *buffer, *shader;
- int len;
-
- if (!f) {
- return NULL;
- }
-
- buffer = (char *) malloc(max);
- len = fread(buffer, 1, max, f);
- buffer[len] = 0;
-
- fclose(f);
-
- shader = _mesa_strdup(buffer);
- free(buffer);
-
- return shader;
-}
-
-
-/**
- * Called via glShaderSource() and glShaderSourceARB() API functions.
- * Basically, concatenate the source code strings into one long string
- * and pass it to _mesa_shader_source().
- */
-void GLAPIENTRY
-_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
- const GLcharARB ** string, const GLint * length)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLint *offsets;
- GLsizei i, totalLength;
- GLcharARB *source;
- GLuint checksum;
-
- if (!shaderObj || string == NULL) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
- return;
- }
-
- /*
- * This array holds offsets of where the appropriate string ends, thus the
- * last element will be set to the total length of the source code.
- */
- offsets = (GLint *) malloc(count * sizeof(GLint));
- if (offsets == NULL) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
- return;
- }
-
- for (i = 0; i < count; i++) {
- if (string[i] == NULL) {
- free((GLvoid *) offsets);
- _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
- return;
- }
- if (length == NULL || length[i] < 0)
- offsets[i] = strlen(string[i]);
- else
- offsets[i] = length[i];
- /* accumulate string lengths */
- if (i > 0)
- offsets[i] += offsets[i - 1];
- }
-
- /* Total length of source string is sum off all strings plus two.
- * One extra byte for terminating zero, another extra byte to silence
- * valgrind warnings in the parser/grammer code.
- */
- totalLength = offsets[count - 1] + 2;
- source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
- if (source == NULL) {
- free((GLvoid *) offsets);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
- return;
- }
-
- for (i = 0; i < count; i++) {
- GLint start = (i > 0) ? offsets[i - 1] : 0;
- memcpy(source + start, string[i],
- (offsets[i] - start) * sizeof(GLcharARB));
- }
- source[totalLength - 1] = '\0';
- source[totalLength - 2] = '\0';
-
- if (SHADER_SUBST) {
- /* Compute the shader's source code checksum then try to open a file
- * named newshader_<CHECKSUM>. If it exists, use it in place of the
- * original shader source code. For debugging.
- */
- char filename[100];
- GLcharARB *newSource;
-
- checksum = _mesa_str_checksum(source);
-
- _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
-
- newSource = read_shader(filename);
- if (newSource) {
- fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
- shaderObj, checksum, filename);
- free(source);
- source = newSource;
- }
- }
-
- shader_source(ctx, shaderObj, source);
-
- if (SHADER_SUBST) {
- struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
- if (sh)
- sh->SourceChecksum = checksum; /* save original checksum */
- }
-
- free(offsets);
-}
-
-
-void GLAPIENTRY
-_mesa_UseProgramObjectARB(GLhandleARB program)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_shader_program *shProg;
- struct gl_transform_feedback_object *obj =
- ctx->TransformFeedback.CurrentObject;
-
- if (obj->Active) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUseProgram(transform feedback active)");
- return;
- }
-
- if (program) {
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
- if (!shProg) {
- return;
- }
- if (!shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUseProgram(program %u not linked)", program);
- return;
- }
-
- /* debug code */
- if (ctx->Shader.Flags & GLSL_USE_PROG) {
- print_shader_info(shProg);
- }
- }
- else {
- shProg = NULL;
- }
-
- _mesa_use_program(ctx, shProg);
-}
-
-
-void GLAPIENTRY
-_mesa_ValidateProgramARB(GLhandleARB program)
-{
- GET_CURRENT_CONTEXT(ctx);
- validate_program(ctx, program);
-}
-
-#ifdef FEATURE_ES2
-
-void GLAPIENTRY
-_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
- GLint* range, GLint* precision)
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) shadertype;
- (void) precisiontype;
- (void) range;
- (void) precision;
- _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-
-void GLAPIENTRY
-_mesa_ReleaseShaderCompiler(void)
-{
- _mesa_destroy_shader_compiler_caches();
-}
-
-
-void GLAPIENTRY
-_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
- const void* binary, GLint length)
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) n;
- (void) shaders;
- (void) binaryformat;
- (void) binary;
- (void) length;
- _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-#endif /* FEATURE_ES2 */
-
-
-#if FEATURE_ARB_geometry_shader4
-
-void GLAPIENTRY
-_mesa_ProgramParameteriARB(GLuint program, GLenum pname,
- GLint value)
-{
- struct gl_shader_program *shProg;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- shProg = _mesa_lookup_shader_program_err(ctx, program,
- "glProgramParameteri");
- if (!shProg)
- return;
-
- switch (pname) {
- case GL_GEOMETRY_VERTICES_OUT_ARB:
- if (value < 1 ||
- (unsigned) value > ctx->Const.GeometryProgram.MaxGeometryOutputVertices) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
- value);
- return;
- }
- shProg->Geom.VerticesOut = value;
- break;
- case GL_GEOMETRY_INPUT_TYPE_ARB:
- switch (value) {
- case GL_POINTS:
- case GL_LINES:
- case GL_LINES_ADJACENCY_ARB:
- case GL_TRIANGLES:
- case GL_TRIANGLES_ADJACENCY_ARB:
- shProg->Geom.InputType = value;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry input type = %s",
- _mesa_lookup_enum_by_nr(value));
- return;
- }
- break;
- case GL_GEOMETRY_OUTPUT_TYPE_ARB:
- switch (value) {
- case GL_POINTS:
- case GL_LINE_STRIP:
- case GL_TRIANGLE_STRIP:
- shProg->Geom.OutputType = value;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry output type = %s",
- _mesa_lookup_enum_by_nr(value));
- return;
- }
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
- break;
- }
-}
-
-#endif
-
-void
-_mesa_use_shader_program(struct gl_context *ctx, GLenum type,
- struct gl_shader_program *shProg)
-{
- use_shader_program(ctx, type, shProg);
-
- if (ctx->Driver.UseProgram)
- ctx->Driver.UseProgram(ctx, shProg);
-}
-
-void GLAPIENTRY
-_mesa_UseShaderProgramEXT(GLenum type, GLuint program)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_shader_program *shProg = NULL;
-
- if (!validate_shader_target(ctx, type)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
- return;
- }
-
- if (ctx->TransformFeedback.CurrentObject->Active) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUseShaderProgramEXT(transform feedback is active)");
- return;
- }
-
- if (program) {
- shProg = _mesa_lookup_shader_program_err(ctx, program,
- "glUseShaderProgramEXT");
- if (shProg == NULL)
- return;
-
- if (!shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUseShaderProgramEXT(program not linked)");
- return;
- }
- }
-
- _mesa_use_shader_program(ctx, type, shProg);
-}
-
-void GLAPIENTRY
-_mesa_ActiveProgramEXT(GLuint program)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_shader_program *shProg = (program != 0)
- ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
- : NULL;
-
- _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
- return;
-}
-
-GLuint GLAPIENTRY
-_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
-{
- GET_CURRENT_CONTEXT(ctx);
- const GLuint shader = create_shader(ctx, type);
- GLuint program = 0;
-
- if (shader) {
- shader_source(ctx, shader, _mesa_strdup(string));
- compile_shader(ctx, shader);
-
- program = create_shader_program(ctx);
- if (program) {
- struct gl_shader_program *shProg;
- struct gl_shader *sh;
- GLint compiled = GL_FALSE;
-
- shProg = _mesa_lookup_shader_program(ctx, program);
- sh = _mesa_lookup_shader(ctx, shader);
-
- get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
- if (compiled) {
- attach_shader(ctx, program, shader);
- link_program(ctx, program);
- detach_shader(ctx, program, shader);
-
-#if 0
- /* Possibly... */
- if (active-user-defined-varyings-in-linked-program) {
- append-error-to-info-log;
- shProg->LinkStatus = GL_FALSE;
- }
-#endif
- }
-
- shProg->InfoLog = talloc_strdup_append(shProg->InfoLog, sh->InfoLog);
- }
-
- delete_shader(ctx, shader);
- }
-
- return program;
-}
-
-/**
- * Plug in shader-related functions into API dispatch table.
- */
-void
-_mesa_init_shader_dispatch(struct _glapi_table *exec)
-{
-#if FEATURE_GL
- /* GL_ARB_vertex/fragment_shader */
- SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
- SET_GetHandleARB(exec, _mesa_GetHandleARB);
- SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
- SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
- SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
- SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
- SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
- SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
- SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
- SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
- SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
- SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
- SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
- SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
- SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
- SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
-
- /* OpenGL 2.0 */
- SET_AttachShader(exec, _mesa_AttachShader);
- SET_CreateProgram(exec, _mesa_CreateProgram);
- SET_CreateShader(exec, _mesa_CreateShader);
- SET_DeleteProgram(exec, _mesa_DeleteProgram);
- SET_DeleteShader(exec, _mesa_DeleteShader);
- SET_DetachShader(exec, _mesa_DetachShader);
- SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
- SET_GetProgramiv(exec, _mesa_GetProgramiv);
- SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
- SET_GetShaderiv(exec, _mesa_GetShaderiv);
- SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
- SET_IsProgram(exec, _mesa_IsProgram);
- SET_IsShader(exec, _mesa_IsShader);
-
-#if FEATURE_ARB_vertex_shader
- SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
- SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
- SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
-#endif
-
-#if FEATURE_ARB_geometry_shader4
- SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB);
-#endif
-
- SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT);
- SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT);
- SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT);
-
- /* GL_EXT_gpu_shader4 / GL 3.0 */
- SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
- SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
-
- /* GL_ARB_ES2_compatibility */
- SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
-
-#endif /* FEATURE_GL */
-}
-
+/* + * Mesa 3-D graphics library + * + * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file shaderapi.c + * \author Brian Paul + * + * Implementation of GLSL-related API functions. + * The glUniform* functions are in uniforms.c + * + * + * XXX things to do: + * 1. Check that the right error code is generated for all _mesa_error() calls. + * 2. Insert FLUSH_VERTICES calls in various places + */ + + +#include "main/glheader.h" +#include "main/context.h" +#include "main/dispatch.h" +#include "main/enums.h" +#include "main/hash.h" +#include "main/mfeatures.h" +#include "main/mtypes.h" +#include "main/shaderapi.h" +#include "main/shaderobj.h" +#include "program/program.h" +#include "program/prog_parameter.h" +#include "program/prog_uniform.h" +#include "talloc.h" +#include <stdbool.h> +#include "../glsl/glsl_parser_extras.h" + +/** Define this to enable shader substitution (see below) */ +#define SHADER_SUBST 0 + + +/** + * Return mask of GLSL_x flags by examining the MESA_GLSL env var. + */ +static GLbitfield +get_shader_flags(void) +{ + GLbitfield flags = 0x0; + const char *env = _mesa_getenv("MESA_GLSL"); + + if (env) { + if (strstr(env, "dump")) + flags |= GLSL_DUMP; + if (strstr(env, "log")) + flags |= GLSL_LOG; + if (strstr(env, "nopvert")) + flags |= GLSL_NOP_VERT; + if (strstr(env, "nopfrag")) + flags |= GLSL_NOP_FRAG; + if (strstr(env, "nopt")) + flags |= GLSL_NO_OPT; + else if (strstr(env, "opt")) + flags |= GLSL_OPT; + if (strstr(env, "uniform")) + flags |= GLSL_UNIFORMS; + if (strstr(env, "useprog")) + flags |= GLSL_USE_PROG; + } + + return flags; +} + + +/** + * Initialize context's shader state. + */ +void +_mesa_init_shader_state(struct gl_context *ctx) +{ + /* Device drivers may override these to control what kind of instructions + * are generated by the GLSL compiler. + */ + struct gl_shader_compiler_options options; + gl_shader_type sh; + + memset(&options, 0, sizeof(options)); + options.MaxUnrollIterations = 32; + + /* Default pragma settings */ + options.DefaultPragmas.Optimize = GL_TRUE; + + for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) + memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options)); + + ctx->Shader.Flags = get_shader_flags(); +} + + +/** + * Free the per-context shader-related state. + */ +void +_mesa_free_shader_state(struct gl_context *ctx) +{ + _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentVertexProgram, NULL); + _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentGeometryProgram, + NULL); + _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram, + NULL); + _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); +} + + +/** + * Return the size of the given GLSL datatype, in floats (components). + */ +GLint +_mesa_sizeof_glsl_type(GLenum type) +{ + switch (type) { + case GL_FLOAT: + case GL_INT: + case GL_BOOL: + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_2D_RECT_ARB: + case GL_SAMPLER_2D_RECT_SHADOW_ARB: + case GL_SAMPLER_1D_ARRAY_EXT: + case GL_SAMPLER_2D_ARRAY_EXT: + case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: + case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: + case GL_SAMPLER_CUBE_SHADOW_EXT: + return 1; + case GL_FLOAT_VEC2: + case GL_INT_VEC2: + case GL_UNSIGNED_INT_VEC2: + case GL_BOOL_VEC2: + return 2; + case GL_FLOAT_VEC3: + case GL_INT_VEC3: + case GL_UNSIGNED_INT_VEC3: + case GL_BOOL_VEC3: + return 3; + case GL_FLOAT_VEC4: + case GL_INT_VEC4: + case GL_UNSIGNED_INT_VEC4: + case GL_BOOL_VEC4: + return 4; + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + return 8; /* two float[4] vectors */ + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3x4: + return 12; /* three float[4] vectors */ + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + return 16; /* four float[4] vectors */ + default: + _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()"); + return 1; + } +} + + +/** + * Copy string from <src> to <dst>, up to maxLength characters, returning + * length of <dst> in <length>. + * \param src the strings source + * \param maxLength max chars to copy + * \param length returns number of chars copied + * \param dst the string destination + */ +void +_mesa_copy_string(GLchar *dst, GLsizei maxLength, + GLsizei *length, const GLchar *src) +{ + GLsizei len; + for (len = 0; len < maxLength - 1 && src && src[len]; len++) + dst[len] = src[len]; + if (maxLength > 0) + dst[len] = 0; + if (length) + *length = len; +} + + + +/** + * Confirm that the a shader type is valid and supported by the implementation + * + * \param ctx Current GL context + * \param type Shader target + * + */ +static bool +validate_shader_target(const struct gl_context *ctx, GLenum type) +{ + switch (type) { +#if FEATURE_ARB_fragment_shader + case GL_FRAGMENT_SHADER: + return ctx->Extensions.ARB_fragment_shader; +#endif +#if FEATURE_ARB_vertex_shader + case GL_VERTEX_SHADER: + return ctx->Extensions.ARB_vertex_shader; +#endif +#if FEATURE_ARB_geometry_shader4 + case GL_GEOMETRY_SHADER_ARB: + return ctx->Extensions.ARB_geometry_shader4; +#endif + default: + return false; + } +} + + +/** + * Find the length of the longest transform feedback varying name + * which was specified with glTransformFeedbackVaryings(). + */ +static GLint +longest_feedback_varying_name(const struct gl_shader_program *shProg) +{ + GLuint i; + GLint max = 0; + for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { + GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]); + if (len > max) + max = len; + } + return max; +} + + + +static GLboolean +is_program(struct gl_context *ctx, GLuint name) +{ + struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name); + return shProg ? GL_TRUE : GL_FALSE; +} + + +static GLboolean +is_shader(struct gl_context *ctx, GLuint name) +{ + struct gl_shader *shader = _mesa_lookup_shader(ctx, name); + return shader ? GL_TRUE : GL_FALSE; +} + + +/** + * Attach shader to a shader program. + */ +static void +attach_shader(struct gl_context *ctx, GLuint program, GLuint shader) +{ + struct gl_shader_program *shProg; + struct gl_shader *sh; + GLuint i, n; + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader"); + if (!shProg) + return; + + sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader"); + if (!sh) { + return; + } + + n = shProg->NumShaders; + for (i = 0; i < n; i++) { + if (shProg->Shaders[i] == sh) { + /* The shader is already attched to this program. The + * GL_ARB_shader_objects spec says: + * + * "The error INVALID_OPERATION is generated by AttachObjectARB + * if <obj> is already attached to <containerObj>." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); + return; + } + } + + /* grow list */ + shProg->Shaders = (struct gl_shader **) + _mesa_realloc(shProg->Shaders, + n * sizeof(struct gl_shader *), + (n + 1) * sizeof(struct gl_shader *)); + if (!shProg->Shaders) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader"); + return; + } + + /* append */ + shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */ + _mesa_reference_shader(ctx, &shProg->Shaders[n], sh); + shProg->NumShaders++; +} + + +static GLint +get_attrib_location(struct gl_context *ctx, GLuint program, const GLchar *name) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation"); + + if (!shProg) { + return -1; + } + + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetAttribLocation(program not linked)"); + return -1; + } + + if (!name) + return -1; + + if (shProg->VertexProgram) { + const struct gl_program_parameter_list *attribs = + shProg->VertexProgram->Base.Attributes; + if (attribs) { + GLint i = _mesa_lookup_parameter_index(attribs, -1, name); + if (i >= 0) { + return attribs->Parameters[i].StateIndexes[0]; + } + } + } + return -1; +} + + +static void +bind_attrib_location(struct gl_context *ctx, GLuint program, GLuint index, + const GLchar *name) +{ + struct gl_shader_program *shProg; + const GLint size = -1; /* unknown size */ + GLint i, oldIndex; + GLenum datatype = GL_FLOAT_VEC4; + + shProg = _mesa_lookup_shader_program_err(ctx, program, + "glBindAttribLocation"); + if (!shProg) { + return; + } + + if (!name) + return; + + if (strncmp(name, "gl_", 3) == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindAttribLocation(illegal name)"); + return; + } + + if (index >= ctx->Const.VertexProgram.MaxAttribs) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)"); + return; + } + + if (shProg->LinkStatus) { + /* get current index/location for the attribute */ + oldIndex = get_attrib_location(ctx, program, name); + } + else { + oldIndex = -1; + } + + /* this will replace the current value if it's already in the list */ + i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index); + if (i < 0) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation"); + return; + } + + /* + * Note that this attribute binding won't go into effect until + * glLinkProgram is called again. + */ +} + + +static void +bind_frag_data_location(struct gl_context *ctx, GLuint program, + GLuint colorNumber, const GLchar *name) +{ + _mesa_problem(ctx, "bind_frag_data_location() not implemented yet"); +} + + +static GLuint +create_shader(struct gl_context *ctx, GLenum type) +{ + struct gl_shader *sh; + GLuint name; + + if (!validate_shader_target(ctx, type)) { + _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)"); + return 0; + } + + name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); + sh = ctx->Driver.NewShader(ctx, name, type); + _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh); + + return name; +} + + +static GLuint +create_shader_program(struct gl_context *ctx) +{ + GLuint name; + struct gl_shader_program *shProg; + + name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); + + shProg = ctx->Driver.NewShaderProgram(ctx, name); + + _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg); + + assert(shProg->RefCount == 1); + + return name; +} + + +/** + * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's + * DeleteProgramARB. + */ +static void +delete_shader_program(struct gl_context *ctx, GLuint name) +{ + /* + * NOTE: deleting shaders/programs works a bit differently than + * texture objects (and buffer objects, etc). Shader/program + * handles/IDs exist in the hash table until the object is really + * deleted (refcount==0). With texture objects, the handle/ID is + * removed from the hash table in glDeleteTextures() while the tex + * object itself might linger until its refcount goes to zero. + */ + struct gl_shader_program *shProg; + + shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram"); + if (!shProg) + return; + + shProg->DeletePending = GL_TRUE; + + /* effectively, decr shProg's refcount */ + _mesa_reference_shader_program(ctx, &shProg, NULL); +} + + +static void +delete_shader(struct gl_context *ctx, GLuint shader) +{ + struct gl_shader *sh; + + sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader"); + if (!sh) + return; + + sh->DeletePending = GL_TRUE; + + /* effectively, decr sh's refcount */ + _mesa_reference_shader(ctx, &sh, NULL); +} + + +static void +detach_shader(struct gl_context *ctx, GLuint program, GLuint shader) +{ + struct gl_shader_program *shProg; + GLuint n; + GLuint i, j; + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader"); + if (!shProg) + return; + + n = shProg->NumShaders; + + for (i = 0; i < n; i++) { + if (shProg->Shaders[i]->Name == shader) { + /* found it */ + struct gl_shader **newList; + + /* release */ + _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); + + /* alloc new, smaller array */ + newList = (struct gl_shader **) + malloc((n - 1) * sizeof(struct gl_shader *)); + if (!newList) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); + return; + } + for (j = 0; j < i; j++) { + newList[j] = shProg->Shaders[j]; + } + while (++i < n) + newList[j++] = shProg->Shaders[i]; + free(shProg->Shaders); + + shProg->Shaders = newList; + shProg->NumShaders = n - 1; + +#ifdef DEBUG + /* sanity check */ + { + for (j = 0; j < shProg->NumShaders; j++) { + assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER || + shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER); + assert(shProg->Shaders[j]->RefCount > 0); + } + } +#endif + + return; + } + } + + /* not found */ + { + GLenum err; + if (is_shader(ctx, shader)) + err = GL_INVALID_OPERATION; + else if (is_program(ctx, shader)) + err = GL_INVALID_OPERATION; + else + err = GL_INVALID_VALUE; + _mesa_error(ctx, err, "glDetachProgram(shader)"); + return; + } +} + + +static void +get_active_attrib(struct gl_context *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *nameOut) +{ + const struct gl_program_parameter_list *attribs = NULL; + struct gl_shader_program *shProg; + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); + if (!shProg) + return; + + if (shProg->VertexProgram) + attribs = shProg->VertexProgram->Base.Attributes; + + if (!attribs || index >= attribs->NumParameters) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); + return; + } + + _mesa_copy_string(nameOut, maxLength, length, + attribs->Parameters[index].Name); + + if (size) + *size = attribs->Parameters[index].Size + / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType); + + if (type) + *type = attribs->Parameters[index].DataType; +} + + +/** + * Return list of shaders attached to shader program. + */ +static void +get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj) +{ + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders"); + if (shProg) { + GLuint i; + for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) { + obj[i] = shProg->Shaders[i]->Name; + } + if (count) + *count = i; + } +} + + +static GLint +get_frag_data_location(struct gl_context *ctx, GLuint program, + const GLchar *name) +{ + _mesa_problem(ctx, "get_frag_data_location() not implemented yet"); + return -1; +} + + + +/** + * glGetHandleARB() - return ID/name of currently bound shader program. + */ +static GLuint +get_handle(struct gl_context *ctx, GLenum pname) +{ + if (pname == GL_PROGRAM_OBJECT_ARB) { + if (ctx->Shader.ActiveProgram) + return ctx->Shader.ActiveProgram->Name; + else + return 0; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); + return 0; + } +} + + +/** + * glGetProgramiv() - get shader program state. + * Note that this is for GLSL shader programs, not ARB vertex/fragment + * programs (see glGetProgramivARB). + */ +static void +get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) +{ + const struct gl_program_parameter_list *attribs; + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); + return; + } + + if (shProg->VertexProgram) + attribs = shProg->VertexProgram->Base.Attributes; + else + attribs = NULL; + + switch (pname) { + case GL_DELETE_STATUS: + *params = shProg->DeletePending; + break; + case GL_LINK_STATUS: + *params = shProg->LinkStatus; + break; + case GL_VALIDATE_STATUS: + *params = shProg->Validated; + break; + case GL_INFO_LOG_LENGTH: + *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; + break; + case GL_ATTACHED_SHADERS: + *params = shProg->NumShaders; + break; + case GL_ACTIVE_ATTRIBUTES: + *params = attribs ? attribs->NumParameters : 0; + break; + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1; + break; + case GL_ACTIVE_UNIFORMS: + *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0; + break; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + *params = _mesa_longest_uniform_name(shProg->Uniforms); + if (*params > 0) + (*params)++; /* add one for terminating zero */ + break; + case GL_PROGRAM_BINARY_LENGTH_OES: + *params = 0; + break; +#if FEATURE_EXT_transform_feedback + case GL_TRANSFORM_FEEDBACK_VARYINGS: + *params = shProg->TransformFeedback.NumVarying; + break; + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + *params = longest_feedback_varying_name(shProg) + 1; + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + *params = shProg->TransformFeedback.BufferMode; + break; +#endif +#if FEATURE_ARB_geometry_shader4 + case GL_GEOMETRY_VERTICES_OUT_ARB: + *params = shProg->Geom.VerticesOut; + break; + case GL_GEOMETRY_INPUT_TYPE_ARB: + *params = shProg->Geom.InputType; + break; + case GL_GEOMETRY_OUTPUT_TYPE_ARB: + *params = shProg->Geom.OutputType; + break; +#endif + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); + return; + } +} + + +/** + * glGetShaderiv() - get GLSL shader state + */ +static void +get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params) +{ + struct gl_shader *shader = + _mesa_lookup_shader_err(ctx, name, "glGetShaderiv"); + + if (!shader) { + return; + } + + switch (pname) { + case GL_SHADER_TYPE: + *params = shader->Type; + break; + case GL_DELETE_STATUS: + *params = shader->DeletePending; + break; + case GL_COMPILE_STATUS: + *params = shader->CompileStatus; + break; + case GL_INFO_LOG_LENGTH: + *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0; + break; + case GL_SHADER_SOURCE_LENGTH: + *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); + return; + } +} + + +static void +get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); + return; + } + _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog); +} + + +static void +get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); + if (!sh) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)"); + return; + } + _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog); +} + + +/** + * Return shader source code. + */ +static void +get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *sourceOut) +{ + struct gl_shader *sh; + sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); + if (!sh) { + return; + } + _mesa_copy_string(sourceOut, maxLength, length, sh->Source); +} + + +/** + * Set/replace shader source code. + */ +static void +shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source) +{ + struct gl_shader *sh; + + sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource"); + if (!sh) + return; + + /* free old shader source string and install new one */ + if (sh->Source) { + free((void *) sh->Source); + } + sh->Source = source; + sh->CompileStatus = GL_FALSE; +#ifdef DEBUG + sh->SourceChecksum = _mesa_str_checksum(sh->Source); +#endif +} + + +/** + * Compile a shader. + */ +static void +compile_shader(struct gl_context *ctx, GLuint shaderObj) +{ + struct gl_shader *sh; + struct gl_shader_compiler_options *options; + + sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader"); + if (!sh) + return; + + options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)]; + + /* set default pragma state for shader */ + sh->Pragmas = options->DefaultPragmas; + + /* this call will set the sh->CompileStatus field to indicate if + * compilation was successful. + */ + _mesa_glsl_compile_shader(ctx, sh); +} + + +/** + * Link a program's shaders. + */ +static void +link_program(struct gl_context *ctx, GLuint program) +{ + struct gl_shader_program *shProg; + struct gl_transform_feedback_object *obj = + ctx->TransformFeedback.CurrentObject; + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram"); + if (!shProg) + return; + + if (obj->Active + && (shProg == ctx->Shader.CurrentVertexProgram + || shProg == ctx->Shader.CurrentGeometryProgram + || shProg == ctx->Shader.CurrentFragmentProgram)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glLinkProgram(transform feedback active"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + _mesa_glsl_link_shader(ctx, shProg); + + /* debug code */ + if (0) { + GLuint i; + + printf("Link %u shaders in program %u: %s\n", + shProg->NumShaders, shProg->Name, + shProg->LinkStatus ? "Success" : "Failed"); + + for (i = 0; i < shProg->NumShaders; i++) { + printf(" shader %u, type 0x%x\n", + shProg->Shaders[i]->Name, + shProg->Shaders[i]->Type); + } + } +} + + +/** + * Print basic shader info (for debug). + */ +static void +print_shader_info(const struct gl_shader_program *shProg) +{ + GLuint i; + + printf("Mesa: glUseProgram(%u)\n", shProg->Name); + for (i = 0; i < shProg->NumShaders; i++) { + const char *s; + switch (shProg->Shaders[i]->Type) { + case GL_VERTEX_SHADER: + s = "vertex"; + break; + case GL_FRAGMENT_SHADER: + s = "fragment"; + break; + case GL_GEOMETRY_SHADER: + s = "geometry"; + break; + default: + s = ""; + } + printf(" %s shader %u, checksum %u\n", s, + shProg->Shaders[i]->Name, + shProg->Shaders[i]->SourceChecksum); + } + if (shProg->VertexProgram) + printf(" vert prog %u\n", shProg->VertexProgram->Base.Id); + if (shProg->FragmentProgram) + printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id); +} + + +/** + * Use the named shader program for subsequent glUniform calls + */ +void +_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, + const char *caller) +{ + if ((shProg != NULL) && !shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(program %u not linked)", caller, shProg->Name); + return; + } + + if (ctx->Shader.ActiveProgram != shProg) { + _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg); + } +} + +/** + */ +static bool +use_shader_program(struct gl_context *ctx, GLenum type, + struct gl_shader_program *shProg) +{ + struct gl_shader_program **target; + + switch (type) { +#if FEATURE_ARB_vertex_shader + case GL_VERTEX_SHADER: + target = &ctx->Shader.CurrentVertexProgram; + if ((shProg == NULL) + || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) { + shProg = NULL; + } + break; +#endif +#if FEATURE_ARB_geometry_shader4 + case GL_GEOMETRY_SHADER_ARB: + target = &ctx->Shader.CurrentGeometryProgram; + if ((shProg == NULL) + || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) { + shProg = NULL; + } + break; +#endif +#if FEATURE_ARB_fragment_shader + case GL_FRAGMENT_SHADER: + target = &ctx->Shader.CurrentFragmentProgram; + if ((shProg == NULL) + || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) { + shProg = NULL; + } + break; +#endif + default: + return false; + } + + if (*target != shProg) { + FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + _mesa_reference_shader_program(ctx, target, shProg); + return true; + } + + return false; +} + +/** + * Use the named shader program for subsequent rendering. + */ +void +_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) +{ + use_shader_program(ctx, GL_VERTEX_SHADER, shProg); + use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg); + use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg); + _mesa_active_program(ctx, shProg, "glUseProgram"); + + if (ctx->Driver.UseProgram) + ctx->Driver.UseProgram(ctx, shProg); +} + + +/** + * Validate a program's samplers. + * Specifically, check that there aren't two samplers of different types + * pointing to the same texture unit. + * \return GL_TRUE if valid, GL_FALSE if invalid + */ +static GLboolean +validate_samplers(const struct gl_program *prog, char *errMsg) +{ + static const char *targetName[] = { + "TEXTURE_2D_ARRAY", + "TEXTURE_1D_ARRAY", + "TEXTURE_CUBE", + "TEXTURE_3D", + "TEXTURE_RECT", + "TEXTURE_2D", + "TEXTURE_1D", + }; + GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS]; + GLbitfield samplersUsed = prog->SamplersUsed; + GLuint i; + + assert(Elements(targetName) == NUM_TEXTURE_TARGETS); + + if (samplersUsed == 0x0) + return GL_TRUE; + + for (i = 0; i < Elements(targetUsed); i++) + targetUsed[i] = -1; + + /* walk over bits which are set in 'samplers' */ + while (samplersUsed) { + GLuint unit; + gl_texture_index target; + GLint sampler = _mesa_ffs(samplersUsed) - 1; + assert(sampler >= 0); + assert(sampler < MAX_TEXTURE_IMAGE_UNITS); + unit = prog->SamplerUnits[sampler]; + target = prog->SamplerTargets[sampler]; + if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) { + _mesa_snprintf(errMsg, 100, + "Texture unit %d is accessed both as %s and %s", + unit, targetName[targetUsed[unit]], targetName[target]); + return GL_FALSE; + } + targetUsed[unit] = target; + samplersUsed ^= (1 << sampler); + } + + return GL_TRUE; +} + + +/** + * Do validation of the given shader program. + * \param errMsg returns error message if validation fails. + * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg) + */ +static GLboolean +validate_shader_program(const struct gl_shader_program *shProg, + char *errMsg) +{ + const struct gl_vertex_program *vp = shProg->VertexProgram; + const struct gl_fragment_program *fp = shProg->FragmentProgram; + + if (!shProg->LinkStatus) { + return GL_FALSE; + } + + /* From the GL spec, a program is invalid if any of these are true: + + any two active samplers in the current program object are of + different types, but refer to the same texture image unit, + + any active sampler in the current program object refers to a texture + image unit where fixed-function fragment processing accesses a + texture target that does not match the sampler type, or + + the sum of the number of active samplers in the program and the + number of texture image units enabled for fixed-function fragment + processing exceeds the combined limit on the total number of texture + image units allowed. + */ + + + /* + * Check: any two active samplers in the current program object are of + * different types, but refer to the same texture image unit, + */ + if (vp && !validate_samplers(&vp->Base, errMsg)) { + return GL_FALSE; + } + if (fp && !validate_samplers(&fp->Base, errMsg)) { + return GL_FALSE; + } + + return GL_TRUE; +} + + +/** + * Called via glValidateProgram() + */ +static void +validate_program(struct gl_context *ctx, GLuint program) +{ + struct gl_shader_program *shProg; + char errMsg[100]; + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); + if (!shProg) { + return; + } + + shProg->Validated = validate_shader_program(shProg, errMsg); + if (!shProg->Validated) { + /* update info log */ + if (shProg->InfoLog) { + talloc_free(shProg->InfoLog); + } + shProg->InfoLog = talloc_strdup(shProg, errMsg); + } +} + + + +void GLAPIENTRY +_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader) +{ + GET_CURRENT_CONTEXT(ctx); + attach_shader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_AttachShader(GLuint program, GLuint shader) +{ + GET_CURRENT_CONTEXT(ctx); + attach_shader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index, + const GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + bind_attrib_location(ctx, program, index, name); +} + + +/* GL_EXT_gpu_shader4, GL3 */ +void GLAPIENTRY +_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, + const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + bind_frag_data_location(ctx, program, colorNumber, name); +} + + +void GLAPIENTRY +_mesa_CompileShaderARB(GLhandleARB shaderObj) +{ + GET_CURRENT_CONTEXT(ctx); + compile_shader(ctx, shaderObj); +} + + +GLuint GLAPIENTRY +_mesa_CreateShader(GLenum type) +{ + GET_CURRENT_CONTEXT(ctx); + return create_shader(ctx, type); +} + + +GLhandleARB GLAPIENTRY +_mesa_CreateShaderObjectARB(GLenum type) +{ + GET_CURRENT_CONTEXT(ctx); + return create_shader(ctx, type); +} + + +GLuint GLAPIENTRY +_mesa_CreateProgram(void) +{ + GET_CURRENT_CONTEXT(ctx); + return create_shader_program(ctx); +} + + +GLhandleARB GLAPIENTRY +_mesa_CreateProgramObjectARB(void) +{ + GET_CURRENT_CONTEXT(ctx); + return create_shader_program(ctx); +} + + +void GLAPIENTRY +_mesa_DeleteObjectARB(GLhandleARB obj) +{ + if (obj) { + GET_CURRENT_CONTEXT(ctx); + if (is_program(ctx, obj)) { + delete_shader_program(ctx, obj); + } + else if (is_shader(ctx, obj)) { + delete_shader(ctx, obj); + } + else { + /* error? */ + } + } +} + + +void GLAPIENTRY +_mesa_DeleteProgram(GLuint name) +{ + if (name) { + GET_CURRENT_CONTEXT(ctx); + delete_shader_program(ctx, name); + } +} + + +void GLAPIENTRY +_mesa_DeleteShader(GLuint name) +{ + if (name) { + GET_CURRENT_CONTEXT(ctx); + delete_shader(ctx, name); + } +} + + +void GLAPIENTRY +_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader) +{ + GET_CURRENT_CONTEXT(ctx); + detach_shader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_DetachShader(GLuint program, GLuint shader) +{ + GET_CURRENT_CONTEXT(ctx); + detach_shader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index, + GLsizei maxLength, GLsizei * length, GLint * size, + GLenum * type, GLcharARB * name) +{ + GET_CURRENT_CONTEXT(ctx); + get_active_attrib(ctx, program, index, maxLength, length, size, type, name); +} + + +void GLAPIENTRY +_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount, + GLsizei * count, GLhandleARB * obj) +{ + GET_CURRENT_CONTEXT(ctx); + get_attached_shaders(ctx, container, maxCount, count, obj); +} + + +void GLAPIENTRY +_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj) +{ + GET_CURRENT_CONTEXT(ctx); + get_attached_shaders(ctx, program, maxCount, count, obj); +} + + +GLint GLAPIENTRY +_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name) +{ + GET_CURRENT_CONTEXT(ctx); + return get_attrib_location(ctx, program, name); +} + + +/* GL_EXT_gpu_shader4, GL3 */ +GLint GLAPIENTRY +_mesa_GetFragDataLocation(GLuint program, const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + return get_frag_data_location(ctx, program, name); +} + + + +void GLAPIENTRY +_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length, + GLcharARB * infoLog) +{ + GET_CURRENT_CONTEXT(ctx); + if (is_program(ctx, object)) { + get_program_info_log(ctx, object, maxLength, length, infoLog); + } + else if (is_shader(ctx, object)) { + get_shader_info_log(ctx, object, maxLength, length, infoLog); + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB"); + } +} + + +void GLAPIENTRY +_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + /* Implement in terms of GetProgramiv, GetShaderiv */ + if (is_program(ctx, object)) { + if (pname == GL_OBJECT_TYPE_ARB) { + *params = GL_PROGRAM_OBJECT_ARB; + } + else { + get_programiv(ctx, object, pname, params); + } + } + else if (is_shader(ctx, object)) { + if (pname == GL_OBJECT_TYPE_ARB) { + *params = GL_SHADER_OBJECT_ARB; + } + else { + get_shaderiv(ctx, object, pname, params); + } + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); + } +} + + +void GLAPIENTRY +_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname, + GLfloat *params) +{ + GLint iparams[1]; /* XXX is one element enough? */ + _mesa_GetObjectParameterivARB(object, pname, iparams); + params[0] = (GLfloat) iparams[0]; +} + + +void GLAPIENTRY +_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + get_programiv(ctx, program, pname, params); +} + + +void GLAPIENTRY +_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + get_shaderiv(ctx, shader, pname, params); +} + + +void GLAPIENTRY +_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + GET_CURRENT_CONTEXT(ctx); + get_program_info_log(ctx, program, bufSize, length, infoLog); +} + + +void GLAPIENTRY +_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + GET_CURRENT_CONTEXT(ctx); + get_shader_info_log(ctx, shader, bufSize, length, infoLog); +} + + +void GLAPIENTRY +_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength, + GLsizei *length, GLcharARB *sourceOut) +{ + GET_CURRENT_CONTEXT(ctx); + get_shader_source(ctx, shader, maxLength, length, sourceOut); +} + + +GLhandleARB GLAPIENTRY +_mesa_GetHandleARB(GLenum pname) +{ + GET_CURRENT_CONTEXT(ctx); + return get_handle(ctx, pname); +} + + +GLboolean GLAPIENTRY +_mesa_IsProgram(GLuint name) +{ + GET_CURRENT_CONTEXT(ctx); + return is_program(ctx, name); +} + + +GLboolean GLAPIENTRY +_mesa_IsShader(GLuint name) +{ + GET_CURRENT_CONTEXT(ctx); + return is_shader(ctx, name); +} + + +void GLAPIENTRY +_mesa_LinkProgramARB(GLhandleARB programObj) +{ + GET_CURRENT_CONTEXT(ctx); + link_program(ctx, programObj); +} + + + +/** + * Read shader source code from a file. + * Useful for debugging to override an app's shader. + */ +static GLcharARB * +read_shader(const char *fname) +{ + const int max = 50*1000; + FILE *f = fopen(fname, "r"); + GLcharARB *buffer, *shader; + int len; + + if (!f) { + return NULL; + } + + buffer = (char *) malloc(max); + len = fread(buffer, 1, max, f); + buffer[len] = 0; + + fclose(f); + + shader = _mesa_strdup(buffer); + free(buffer); + + return shader; +} + + +/** + * Called via glShaderSource() and glShaderSourceARB() API functions. + * Basically, concatenate the source code strings into one long string + * and pass it to _mesa_shader_source(). + */ +void GLAPIENTRY +_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, + const GLcharARB ** string, const GLint * length) +{ + GET_CURRENT_CONTEXT(ctx); + GLint *offsets; + GLsizei i, totalLength; + GLcharARB *source; + GLuint checksum; + + if (!shaderObj || string == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); + return; + } + + /* + * This array holds offsets of where the appropriate string ends, thus the + * last element will be set to the total length of the source code. + */ + offsets = (GLint *) malloc(count * sizeof(GLint)); + if (offsets == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) { + if (string[i] == NULL) { + free((GLvoid *) offsets); + _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)"); + return; + } + if (length == NULL || length[i] < 0) + offsets[i] = strlen(string[i]); + else + offsets[i] = length[i]; + /* accumulate string lengths */ + if (i > 0) + offsets[i] += offsets[i - 1]; + } + + /* Total length of source string is sum off all strings plus two. + * One extra byte for terminating zero, another extra byte to silence + * valgrind warnings in the parser/grammer code. + */ + totalLength = offsets[count - 1] + 2; + source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB)); + if (source == NULL) { + free((GLvoid *) offsets); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) { + GLint start = (i > 0) ? offsets[i - 1] : 0; + memcpy(source + start, string[i], + (offsets[i] - start) * sizeof(GLcharARB)); + } + source[totalLength - 1] = '\0'; + source[totalLength - 2] = '\0'; + + if (SHADER_SUBST) { + /* Compute the shader's source code checksum then try to open a file + * named newshader_<CHECKSUM>. If it exists, use it in place of the + * original shader source code. For debugging. + */ + char filename[100]; + GLcharARB *newSource; + + checksum = _mesa_str_checksum(source); + + _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum); + + newSource = read_shader(filename); + if (newSource) { + fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n", + shaderObj, checksum, filename); + free(source); + source = newSource; + } + } + + shader_source(ctx, shaderObj, source); + + if (SHADER_SUBST) { + struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj); + if (sh) + sh->SourceChecksum = checksum; /* save original checksum */ + } + + free(offsets); +} + + +void GLAPIENTRY +_mesa_UseProgramObjectARB(GLhandleARB program) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg; + struct gl_transform_feedback_object *obj = + ctx->TransformFeedback.CurrentObject; + + if (obj->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUseProgram(transform feedback active)"); + return; + } + + if (program) { + shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); + if (!shProg) { + return; + } + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUseProgram(program %u not linked)", program); + return; + } + + /* debug code */ + if (ctx->Shader.Flags & GLSL_USE_PROG) { + print_shader_info(shProg); + } + } + else { + shProg = NULL; + } + + _mesa_use_program(ctx, shProg); +} + + +void GLAPIENTRY +_mesa_ValidateProgramARB(GLhandleARB program) +{ + GET_CURRENT_CONTEXT(ctx); + validate_program(ctx, program); +} + +#ifdef FEATURE_ES2 + +void GLAPIENTRY +_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, + GLint* range, GLint* precision) +{ + const struct gl_program_constants *limits; + const struct gl_precision *p; + GET_CURRENT_CONTEXT(ctx); + + switch (shadertype) { + case GL_VERTEX_SHADER: + limits = &ctx->Const.VertexProgram; + break; + case GL_FRAGMENT_SHADER: + limits = &ctx->Const.FragmentProgram; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetShaderPrecisionFormat(shadertype)"); + return; + } + + switch (precisiontype) { + case GL_LOW_FLOAT: + p = &limits->LowFloat; + break; + case GL_MEDIUM_FLOAT: + p = &limits->MediumFloat; + break; + case GL_HIGH_FLOAT: + p = &limits->HighFloat; + break; + case GL_LOW_INT: + p = &limits->LowInt; + break; + case GL_MEDIUM_INT: + p = &limits->MediumInt; + break; + case GL_HIGH_INT: + p = &limits->HighInt; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetShaderPrecisionFormat(precisiontype)"); + return; + } + + range[0] = p->RangeMin; + range[1] = p->RangeMax; + precision[0] = p->Precision; +} + + +void GLAPIENTRY +_mesa_ReleaseShaderCompiler(void) +{ + _mesa_destroy_shader_compiler_caches(); +} + + +void GLAPIENTRY +_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, + const void* binary, GLint length) +{ + GET_CURRENT_CONTEXT(ctx); + (void) n; + (void) shaders; + (void) binaryformat; + (void) binary; + (void) length; + _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); +} + +#endif /* FEATURE_ES2 */ + + +#if FEATURE_ARB_geometry_shader4 + +void GLAPIENTRY +_mesa_ProgramParameteriARB(GLuint program, GLenum pname, + GLint value) +{ + struct gl_shader_program *shProg; + GET_CURRENT_CONTEXT(ctx); + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + shProg = _mesa_lookup_shader_program_err(ctx, program, + "glProgramParameteri"); + if (!shProg) + return; + + switch (pname) { + case GL_GEOMETRY_VERTICES_OUT_ARB: + if (value < 1 || + (unsigned) value > ctx->Const.GeometryProgram.MaxGeometryOutputVertices) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d", + value); + return; + } + shProg->Geom.VerticesOut = value; + break; + case GL_GEOMETRY_INPUT_TYPE_ARB: + switch (value) { + case GL_POINTS: + case GL_LINES: + case GL_LINES_ADJACENCY_ARB: + case GL_TRIANGLES: + case GL_TRIANGLES_ADJACENCY_ARB: + shProg->Geom.InputType = value; + break; + default: + _mesa_error(ctx, GL_INVALID_VALUE, + "glProgramParameteri(geometry input type = %s", + _mesa_lookup_enum_by_nr(value)); + return; + } + break; + case GL_GEOMETRY_OUTPUT_TYPE_ARB: + switch (value) { + case GL_POINTS: + case GL_LINE_STRIP: + case GL_TRIANGLE_STRIP: + shProg->Geom.OutputType = value; + break; + default: + _mesa_error(ctx, GL_INVALID_VALUE, + "glProgramParameteri(geometry output type = %s", + _mesa_lookup_enum_by_nr(value)); + return; + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)", + _mesa_lookup_enum_by_nr(pname)); + break; + } +} + +#endif + +void +_mesa_use_shader_program(struct gl_context *ctx, GLenum type, + struct gl_shader_program *shProg) +{ + use_shader_program(ctx, type, shProg); + + if (ctx->Driver.UseProgram) + ctx->Driver.UseProgram(ctx, shProg); +} + +void GLAPIENTRY +_mesa_UseShaderProgramEXT(GLenum type, GLuint program) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = NULL; + + if (!validate_shader_target(ctx, type)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)"); + return; + } + + if (ctx->TransformFeedback.CurrentObject->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUseShaderProgramEXT(transform feedback is active)"); + return; + } + + if (program) { + shProg = _mesa_lookup_shader_program_err(ctx, program, + "glUseShaderProgramEXT"); + if (shProg == NULL) + return; + + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUseShaderProgramEXT(program not linked)"); + return; + } + } + + _mesa_use_shader_program(ctx, type, shProg); +} + +void GLAPIENTRY +_mesa_ActiveProgramEXT(GLuint program) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = (program != 0) + ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT") + : NULL; + + _mesa_active_program(ctx, shProg, "glActiveProgramEXT"); + return; +} + +GLuint GLAPIENTRY +_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string) +{ + GET_CURRENT_CONTEXT(ctx); + const GLuint shader = create_shader(ctx, type); + GLuint program = 0; + + if (shader) { + shader_source(ctx, shader, _mesa_strdup(string)); + compile_shader(ctx, shader); + + program = create_shader_program(ctx); + if (program) { + struct gl_shader_program *shProg; + struct gl_shader *sh; + GLint compiled = GL_FALSE; + + shProg = _mesa_lookup_shader_program(ctx, program); + sh = _mesa_lookup_shader(ctx, shader); + + get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled); + if (compiled) { + attach_shader(ctx, program, shader); + link_program(ctx, program); + detach_shader(ctx, program, shader); + +#if 0 + /* Possibly... */ + if (active-user-defined-varyings-in-linked-program) { + append-error-to-info-log; + shProg->LinkStatus = GL_FALSE; + } +#endif + } + + shProg->InfoLog = talloc_strdup_append(shProg->InfoLog, sh->InfoLog); + } + + delete_shader(ctx, shader); + } + + return program; +} + +/** + * Plug in shader-related functions into API dispatch table. + */ +void +_mesa_init_shader_dispatch(struct _glapi_table *exec) +{ +#if FEATURE_GL + /* GL_ARB_vertex/fragment_shader */ + SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB); + SET_GetHandleARB(exec, _mesa_GetHandleARB); + SET_DetachObjectARB(exec, _mesa_DetachObjectARB); + SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB); + SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB); + SET_CompileShaderARB(exec, _mesa_CompileShaderARB); + SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB); + SET_AttachObjectARB(exec, _mesa_AttachObjectARB); + SET_LinkProgramARB(exec, _mesa_LinkProgramARB); + SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB); + SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB); + SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB); + SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB); + SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB); + SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB); + SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB); + + /* OpenGL 2.0 */ + SET_AttachShader(exec, _mesa_AttachShader); + SET_CreateProgram(exec, _mesa_CreateProgram); + SET_CreateShader(exec, _mesa_CreateShader); + SET_DeleteProgram(exec, _mesa_DeleteProgram); + SET_DeleteShader(exec, _mesa_DeleteShader); + SET_DetachShader(exec, _mesa_DetachShader); + SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders); + SET_GetProgramiv(exec, _mesa_GetProgramiv); + SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog); + SET_GetShaderiv(exec, _mesa_GetShaderiv); + SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog); + SET_IsProgram(exec, _mesa_IsProgram); + SET_IsShader(exec, _mesa_IsShader); + +#if FEATURE_ARB_vertex_shader + SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB); + SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB); + SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB); +#endif + +#if FEATURE_ARB_geometry_shader4 + SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB); +#endif + + SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT); + SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT); + SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT); + + /* GL_EXT_gpu_shader4 / GL 3.0 */ + SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation); + SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation); + + /* GL_ARB_ES2_compatibility */ + SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler); + +#endif /* FEATURE_GL */ +} + diff --git a/mesalib/src/mesa/program/register_allocate.c b/mesalib/src/mesa/program/register_allocate.c index 93e0cbe78..f984e2f14 100644 --- a/mesalib/src/mesa/program/register_allocate.c +++ b/mesalib/src/mesa/program/register_allocate.c @@ -1,425 +1,458 @@ -/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- *
- */
-
-/** @file register_allocate.c
- *
- * Graph-coloring register allocator.
- */
-
-#include <talloc.h>
-
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "register_allocate.h"
-
-struct ra_reg {
- char *name;
- GLboolean *conflicts;
-};
-
-struct ra_regs {
- struct ra_reg *regs;
- unsigned int count;
-
- struct ra_class **classes;
- unsigned int class_count;
-};
-
-struct ra_class {
- GLboolean *regs;
-
- /**
- * p_B in Runeson/Nyström paper.
- *
- * This is "how many regs are in the set."
- */
- unsigned int p;
-
- /**
- * q_B,C in Runeson/Nyström paper.
- */
- unsigned int *q;
-};
-
-struct ra_node {
- GLboolean *adjacency;
- unsigned int class;
- unsigned int adjacency_count;
- unsigned int reg;
- GLboolean in_stack;
- float spill_cost;
-};
-
-struct ra_graph {
- struct ra_regs *regs;
- /**
- * the variables that need register allocation.
- */
- struct ra_node *nodes;
- unsigned int count; /**< count of nodes. */
-
- unsigned int *stack;
- unsigned int stack_count;
-};
-
-struct ra_regs *
-ra_alloc_reg_set(unsigned int count)
-{
- unsigned int i;
- struct ra_regs *regs;
-
- regs = talloc_zero(NULL, struct ra_regs);
- regs->count = count;
- regs->regs = talloc_zero_array(regs, struct ra_reg, count);
-
- for (i = 0; i < count; i++) {
- regs->regs[i].conflicts = talloc_zero_array(regs->regs, GLboolean, count);
- regs->regs[i].conflicts[i] = GL_TRUE;
- }
-
- return regs;
-}
-
-void
-ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2)
-{
- regs->regs[r1].conflicts[r2] = GL_TRUE;
- regs->regs[r2].conflicts[r1] = GL_TRUE;
-}
-
-unsigned int
-ra_alloc_reg_class(struct ra_regs *regs)
-{
- struct ra_class *class;
-
- regs->classes = talloc_realloc(regs, regs->classes,
- struct ra_class *,
- regs->class_count + 1);
-
- class = talloc_zero(regs, struct ra_class);
- regs->classes[regs->class_count] = class;
-
- class->regs = talloc_zero_array(class, GLboolean, regs->count);
-
- return regs->class_count++;
-}
-
-void
-ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r)
-{
- struct ra_class *class = regs->classes[c];
-
- class->regs[r] = GL_TRUE;
- class->p++;
-}
-
-/**
- * Must be called after all conflicts and register classes have been
- * set up and before the register set is used for allocation.
- */
-void
-ra_set_finalize(struct ra_regs *regs)
-{
- unsigned int b, c;
-
- for (b = 0; b < regs->class_count; b++) {
- regs->classes[b]->q = talloc_array(regs, unsigned int, regs->class_count);
- }
-
- /* Compute, for each class B and C, how many regs of B an
- * allocation to C could conflict with.
- */
- for (b = 0; b < regs->class_count; b++) {
- for (c = 0; c < regs->class_count; c++) {
- unsigned int rc;
- int max_conflicts = 0;
-
- for (rc = 0; rc < regs->count; rc++) {
- unsigned int rb;
- int conflicts = 0;
-
- if (!regs->classes[c]->regs[rc])
- continue;
-
- for (rb = 0; rb < regs->count; rb++) {
- if (regs->classes[b]->regs[rb] &&
- regs->regs[rb].conflicts[rc])
- conflicts++;
- }
- max_conflicts = MAX2(max_conflicts, conflicts);
- }
- regs->classes[b]->q[c] = max_conflicts;
- }
- }
-}
-
-struct ra_graph *
-ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
-{
- struct ra_graph *g;
- unsigned int i;
-
- g = talloc_zero(regs, struct ra_graph);
- g->regs = regs;
- g->nodes = talloc_zero_array(g, struct ra_node, count);
- g->count = count;
-
- g->stack = talloc_zero_array(g, unsigned int, count);
-
- for (i = 0; i < count; i++) {
- g->nodes[i].adjacency = talloc_zero_array(g, GLboolean, count);
- g->nodes[i].adjacency[i] = GL_TRUE;
- g->nodes[i].reg = ~0;
- }
-
- return g;
-}
-
-void
-ra_set_node_class(struct ra_graph *g,
- unsigned int n, unsigned int class)
-{
- g->nodes[n].class = class;
-}
-
-void
-ra_add_node_interference(struct ra_graph *g,
- unsigned int n1, unsigned int n2)
-{
- if (g->nodes[n1].adjacency[n2])
- return;
-
- g->nodes[n1].adjacency[n2] = GL_TRUE;
- g->nodes[n2].adjacency_count++;
- g->nodes[n2].adjacency[n1] = GL_TRUE;
- g->nodes[n2].adjacency_count++;
-}
-
-static GLboolean pq_test(struct ra_graph *g, unsigned int n)
-{
- unsigned int j;
- unsigned int q = 0;
- int n_class = g->nodes[n].class;
-
- for (j = 0; j < g->count; j++) {
- if (j == n || g->nodes[j].in_stack)
- continue;
-
- if (g->nodes[n].adjacency[j]) {
- unsigned int j_class = g->nodes[j].class;
- q += g->regs->classes[n_class]->q[j_class];
- }
- }
-
- return q < g->regs->classes[n_class]->p;
-}
-
-/**
- * Simplifies the interference graph by pushing all
- * trivially-colorable nodes into a stack of nodes to be colored,
- * removing them from the graph, and rinsing and repeating.
- *
- * Returns GL_TRUE if all nodes were removed from the graph. GL_FALSE
- * means that either spilling will be required, or optimistic coloring
- * should be applied.
- */
-GLboolean
-ra_simplify(struct ra_graph *g)
-{
- GLboolean progress = GL_TRUE;
- int i;
-
- while (progress) {
- progress = GL_FALSE;
-
- for (i = g->count - 1; i >= 0; i--) {
- if (g->nodes[i].in_stack)
- continue;
-
- if (pq_test(g, i)) {
- g->stack[g->stack_count] = i;
- g->stack_count++;
- g->nodes[i].in_stack = GL_TRUE;
- progress = GL_TRUE;
- }
- }
- }
-
- for (i = 0; i < g->count; i++) {
- if (!g->nodes[i].in_stack)
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-/**
- * Pops nodes from the stack back into the graph, coloring them with
- * registers as they go.
- *
- * If all nodes were trivially colorable, then this must succeed. If
- * not (optimistic coloring), then it may return GL_FALSE;
- */
-GLboolean
-ra_select(struct ra_graph *g)
-{
- int i;
-
- while (g->stack_count != 0) {
- unsigned int r;
- int n = g->stack[g->stack_count - 1];
- struct ra_class *c = g->regs->classes[g->nodes[n].class];
-
- /* Find the lowest-numbered reg which is not used by a member
- * of the graph adjacent to us.
- */
- for (r = 0; r < g->regs->count; r++) {
- if (!c->regs[r])
- continue;
-
- /* Check if any of our neighbors conflict with this register choice. */
- for (i = 0; i < g->count; i++) {
- if (g->nodes[n].adjacency[i] &&
- !g->nodes[i].in_stack &&
- g->regs->regs[r].conflicts[g->nodes[i].reg]) {
- break;
- }
- }
- if (i == g->count)
- break;
- }
- if (r == g->regs->count)
- return GL_FALSE;
-
- g->nodes[n].reg = r;
- g->nodes[n].in_stack = GL_FALSE;
- g->stack_count--;
- }
-
- return GL_TRUE;
-}
-
-/**
- * Optimistic register coloring: Just push the remaining nodes
- * on the stack. They'll be colored first in ra_select(), and
- * if they succeed then the locally-colorable nodes are still
- * locally-colorable and the rest of the register allocation
- * will succeed.
- */
-void
-ra_optimistic_color(struct ra_graph *g)
-{
- unsigned int i;
-
- for (i = 0; i < g->count; i++) {
- if (g->nodes[i].in_stack)
- continue;
-
- g->stack[g->stack_count] = i;
- g->stack_count++;
- g->nodes[i].in_stack = GL_TRUE;
- }
-}
-
-GLboolean
-ra_allocate_no_spills(struct ra_graph *g)
-{
- if (!ra_simplify(g)) {
- ra_optimistic_color(g);
- }
- return ra_select(g);
-}
-
-unsigned int
-ra_get_node_reg(struct ra_graph *g, unsigned int n)
-{
- return g->nodes[n].reg;
-}
-
-static float
-ra_get_spill_benefit(struct ra_graph *g, unsigned int n)
-{
- int j;
- float benefit = 0;
- int n_class = g->nodes[n].class;
-
- /* Define the benefit of eliminating an interference between n, j
- * through spilling as q(C, B) / p(C). This is similar to the
- * "count number of edges" approach of traditional graph coloring,
- * but takes classes into account.
- */
- for (j = 0; j < g->count; j++) {
- if (j != n && g->nodes[n].adjacency[j]) {
- unsigned int j_class = g->nodes[j].class;
- benefit += ((float)g->regs->classes[n_class]->q[j_class] /
- g->regs->classes[n_class]->p);
- break;
- }
- }
-
- return benefit;
-}
-
-/**
- * Returns a node number to be spilled according to the cost/benefit using
- * the pq test, or -1 if there are no spillable nodes.
- */
-int
-ra_get_best_spill_node(struct ra_graph *g)
-{
- unsigned int best_node = -1;
- unsigned int best_benefit = 0.0;
- unsigned int n;
-
- for (n = 0; n < g->count; n++) {
- float cost = g->nodes[n].spill_cost;
- float benefit;
-
- if (cost <= 0.0)
- continue;
-
- benefit = ra_get_spill_benefit(g, n);
-
- if (benefit / cost > best_benefit) {
- best_benefit = benefit / cost;
- best_node = n;
- }
- }
-
- return best_node;
-}
-
-/**
- * Only nodes with a spill cost set (cost != 0.0) will be considered
- * for register spilling.
- */
-void
-ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost)
-{
- g->nodes[n].spill_cost = cost;
-}
+/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +/** @file register_allocate.c + * + * Graph-coloring register allocator. + */ + +#include <talloc.h> + +#include "main/imports.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "register_allocate.h" + +struct ra_reg { + GLboolean *conflicts; + unsigned int *conflict_list; + unsigned int conflict_list_size; + unsigned int num_conflicts; +}; + +struct ra_regs { + struct ra_reg *regs; + unsigned int count; + + struct ra_class **classes; + unsigned int class_count; +}; + +struct ra_class { + GLboolean *regs; + + /** + * p_B in Runeson/Nyström paper. + * + * This is "how many regs are in the set." + */ + unsigned int p; + + /** + * q_B,C in Runeson/Nyström paper. + */ + unsigned int *q; +}; + +struct ra_node { + GLboolean *adjacency; + unsigned int *adjacency_list; + unsigned int class; + unsigned int adjacency_count; + unsigned int reg; + GLboolean in_stack; + float spill_cost; +}; + +struct ra_graph { + struct ra_regs *regs; + /** + * the variables that need register allocation. + */ + struct ra_node *nodes; + unsigned int count; /**< count of nodes. */ + + unsigned int *stack; + unsigned int stack_count; +}; + +struct ra_regs * +ra_alloc_reg_set(unsigned int count) +{ + unsigned int i; + struct ra_regs *regs; + + regs = talloc_zero(NULL, struct ra_regs); + regs->count = count; + regs->regs = talloc_zero_array(regs, struct ra_reg, count); + + for (i = 0; i < count; i++) { + regs->regs[i].conflicts = talloc_zero_array(regs->regs, GLboolean, count); + regs->regs[i].conflicts[i] = GL_TRUE; + + regs->regs[i].conflict_list = talloc_array(regs->regs, unsigned int, 4); + regs->regs[i].conflict_list_size = 4; + regs->regs[i].conflict_list[0] = i; + regs->regs[i].num_conflicts = 1; + } + + return regs; +} + +static void +ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2) +{ + struct ra_reg *reg1 = ®s->regs[r1]; + + if (reg1->conflict_list_size == reg1->num_conflicts) { + reg1->conflict_list_size *= 2; + reg1->conflict_list = talloc_realloc(regs, + reg1->conflict_list, + unsigned int, + reg1->conflict_list_size); + } + reg1->conflict_list[reg1->num_conflicts++] = r2; + reg1->conflicts[r2] = GL_TRUE; +} + +void +ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2) +{ + if (!regs->regs[r1].conflicts[r2]) { + ra_add_conflict_list(regs, r1, r2); + ra_add_conflict_list(regs, r2, r1); + } +} + +unsigned int +ra_alloc_reg_class(struct ra_regs *regs) +{ + struct ra_class *class; + + regs->classes = talloc_realloc(regs, regs->classes, + struct ra_class *, + regs->class_count + 1); + + class = talloc_zero(regs, struct ra_class); + regs->classes[regs->class_count] = class; + + class->regs = talloc_zero_array(class, GLboolean, regs->count); + + return regs->class_count++; +} + +void +ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r) +{ + struct ra_class *class = regs->classes[c]; + + class->regs[r] = GL_TRUE; + class->p++; +} + +/** + * Must be called after all conflicts and register classes have been + * set up and before the register set is used for allocation. + */ +void +ra_set_finalize(struct ra_regs *regs) +{ + unsigned int b, c; + + for (b = 0; b < regs->class_count; b++) { + regs->classes[b]->q = talloc_array(regs, unsigned int, regs->class_count); + } + + /* Compute, for each class B and C, how many regs of B an + * allocation to C could conflict with. + */ + for (b = 0; b < regs->class_count; b++) { + for (c = 0; c < regs->class_count; c++) { + unsigned int rc; + int max_conflicts = 0; + + for (rc = 0; rc < regs->count; rc++) { + int conflicts = 0; + int i; + + if (!regs->classes[c]->regs[rc]) + continue; + + for (i = 0; i < regs->regs[rc].num_conflicts; i++) { + unsigned int rb = regs->regs[rc].conflict_list[i]; + if (regs->classes[b]->regs[rb]) + conflicts++; + } + max_conflicts = MAX2(max_conflicts, conflicts); + } + regs->classes[b]->q[c] = max_conflicts; + } + } +} + +static void +ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2) +{ + g->nodes[n1].adjacency[n2] = GL_TRUE; + g->nodes[n1].adjacency_list[g->nodes[n1].adjacency_count] = n2; + g->nodes[n1].adjacency_count++; +} + +struct ra_graph * +ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count) +{ + struct ra_graph *g; + unsigned int i; + + g = talloc_zero(regs, struct ra_graph); + g->regs = regs; + g->nodes = talloc_zero_array(g, struct ra_node, count); + g->count = count; + + g->stack = talloc_zero_array(g, unsigned int, count); + + for (i = 0; i < count; i++) { + g->nodes[i].adjacency = talloc_zero_array(g, GLboolean, count); + g->nodes[i].adjacency_list = talloc_array(g, unsigned int, count); + g->nodes[i].adjacency_count = 0; + ra_add_node_adjacency(g, i, i); + g->nodes[i].reg = ~0; + } + + return g; +} + +void +ra_set_node_class(struct ra_graph *g, + unsigned int n, unsigned int class) +{ + g->nodes[n].class = class; +} + +void +ra_add_node_interference(struct ra_graph *g, + unsigned int n1, unsigned int n2) +{ + if (!g->nodes[n1].adjacency[n2]) { + ra_add_node_adjacency(g, n1, n2); + ra_add_node_adjacency(g, n2, n1); + } +} + +static GLboolean pq_test(struct ra_graph *g, unsigned int n) +{ + unsigned int j; + unsigned int q = 0; + int n_class = g->nodes[n].class; + + for (j = 0; j < g->nodes[n].adjacency_count; j++) { + unsigned int n2 = g->nodes[n].adjacency_list[j]; + unsigned int n2_class = g->nodes[n2].class; + + if (n != n2 && !g->nodes[n2].in_stack) { + q += g->regs->classes[n_class]->q[n2_class]; + } + } + + return q < g->regs->classes[n_class]->p; +} + +/** + * Simplifies the interference graph by pushing all + * trivially-colorable nodes into a stack of nodes to be colored, + * removing them from the graph, and rinsing and repeating. + * + * Returns GL_TRUE if all nodes were removed from the graph. GL_FALSE + * means that either spilling will be required, or optimistic coloring + * should be applied. + */ +GLboolean +ra_simplify(struct ra_graph *g) +{ + GLboolean progress = GL_TRUE; + int i; + + while (progress) { + progress = GL_FALSE; + + for (i = g->count - 1; i >= 0; i--) { + if (g->nodes[i].in_stack) + continue; + + if (pq_test(g, i)) { + g->stack[g->stack_count] = i; + g->stack_count++; + g->nodes[i].in_stack = GL_TRUE; + progress = GL_TRUE; + } + } + } + + for (i = 0; i < g->count; i++) { + if (!g->nodes[i].in_stack) + return GL_FALSE; + } + + return GL_TRUE; +} + +/** + * Pops nodes from the stack back into the graph, coloring them with + * registers as they go. + * + * If all nodes were trivially colorable, then this must succeed. If + * not (optimistic coloring), then it may return GL_FALSE; + */ +GLboolean +ra_select(struct ra_graph *g) +{ + int i; + + while (g->stack_count != 0) { + unsigned int r; + int n = g->stack[g->stack_count - 1]; + struct ra_class *c = g->regs->classes[g->nodes[n].class]; + + /* Find the lowest-numbered reg which is not used by a member + * of the graph adjacent to us. + */ + for (r = 0; r < g->regs->count; r++) { + if (!c->regs[r]) + continue; + + /* Check if any of our neighbors conflict with this register choice. */ + for (i = 0; i < g->nodes[n].adjacency_count; i++) { + unsigned int n2 = g->nodes[n].adjacency_list[i]; + + if (!g->nodes[n2].in_stack && + g->regs->regs[r].conflicts[g->nodes[n2].reg]) { + break; + } + } + if (i == g->nodes[n].adjacency_count) + break; + } + if (r == g->regs->count) + return GL_FALSE; + + g->nodes[n].reg = r; + g->nodes[n].in_stack = GL_FALSE; + g->stack_count--; + } + + return GL_TRUE; +} + +/** + * Optimistic register coloring: Just push the remaining nodes + * on the stack. They'll be colored first in ra_select(), and + * if they succeed then the locally-colorable nodes are still + * locally-colorable and the rest of the register allocation + * will succeed. + */ +void +ra_optimistic_color(struct ra_graph *g) +{ + unsigned int i; + + for (i = 0; i < g->count; i++) { + if (g->nodes[i].in_stack) + continue; + + g->stack[g->stack_count] = i; + g->stack_count++; + g->nodes[i].in_stack = GL_TRUE; + } +} + +GLboolean +ra_allocate_no_spills(struct ra_graph *g) +{ + if (!ra_simplify(g)) { + ra_optimistic_color(g); + } + return ra_select(g); +} + +unsigned int +ra_get_node_reg(struct ra_graph *g, unsigned int n) +{ + return g->nodes[n].reg; +} + +static float +ra_get_spill_benefit(struct ra_graph *g, unsigned int n) +{ + int j; + float benefit = 0; + int n_class = g->nodes[n].class; + + /* Define the benefit of eliminating an interference between n, n2 + * through spilling as q(C, B) / p(C). This is similar to the + * "count number of edges" approach of traditional graph coloring, + * but takes classes into account. + */ + for (j = 0; j < g->nodes[n].adjacency_count; j++) { + unsigned int n2 = g->nodes[n].adjacency_list[j]; + if (n != n2) { + unsigned int n2_class = g->nodes[n2].class; + benefit += ((float)g->regs->classes[n_class]->q[n2_class] / + g->regs->classes[n_class]->p); + } + } + + return benefit; +} + +/** + * Returns a node number to be spilled according to the cost/benefit using + * the pq test, or -1 if there are no spillable nodes. + */ +int +ra_get_best_spill_node(struct ra_graph *g) +{ + unsigned int best_node = -1; + unsigned int best_benefit = 0.0; + unsigned int n; + + for (n = 0; n < g->count; n++) { + float cost = g->nodes[n].spill_cost; + float benefit; + + if (cost <= 0.0) + continue; + + benefit = ra_get_spill_benefit(g, n); + + if (benefit / cost > best_benefit) { + best_benefit = benefit / cost; + best_node = n; + } + } + + return best_node; +} + +/** + * Only nodes with a spill cost set (cost != 0.0) will be considered + * for register spilling. + */ +void +ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost) +{ + g->nodes[n].spill_cost = cost; +} diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 0a1c473cc..974fd78d7 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -1,468 +1,468 @@ -/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * Copyright (c) 2008 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "main/macros.h"
-#include "main/mfeatures.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_screen.h"
-
-#include "st_context.h"
-#include "st_extensions.h"
-
-
-static int _min(int a, int b)
-{
- return (a < b) ? a : b;
-}
-
-static float _maxf(float a, float b)
-{
- return (a > b) ? a : b;
-}
-
-static int _clamp(int a, int min, int max)
-{
- if (a < min)
- return min;
- else if (a > max)
- return max;
- else
- return a;
-}
-
-
-/**
- * Query driver to get implementation limits.
- * Note that we have to limit/clamp against Mesa's internal limits too.
- */
-void st_init_limits(struct st_context *st)
-{
- struct pipe_screen *screen = st->pipe->screen;
- struct gl_constants *c = &st->ctx->Const;
- gl_shader_type sh;
-
- c->MaxTextureLevels
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
- MAX_TEXTURE_LEVELS);
-
- c->Max3DTextureLevels
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS),
- MAX_3D_TEXTURE_LEVELS);
-
- c->MaxCubeTextureLevels
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS),
- MAX_CUBE_TEXTURE_LEVELS);
-
- c->MaxTextureRectSize
- = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE);
-
- c->MaxTextureImageUnits
- = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS),
- MAX_TEXTURE_IMAGE_UNITS);
-
- c->MaxVertexTextureImageUnits
- = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS),
- MAX_VERTEX_TEXTURE_IMAGE_UNITS);
-
- c->MaxCombinedTextureImageUnits
- = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS),
- MAX_COMBINED_TEXTURE_IMAGE_UNITS);
-
- c->MaxTextureCoordUnits
- = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS);
-
- c->MaxTextureUnits = _min(c->MaxTextureImageUnits, c->MaxTextureCoordUnits);
-
- c->MaxDrawBuffers
- = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
- 1, MAX_DRAW_BUFFERS);
-
- c->MaxLineWidth
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH));
- c->MaxLineWidthAA
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH_AA));
-
- c->MaxPointSize
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH));
- c->MaxPointSizeAA
- = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA));
- /* called after _mesa_create_context/_mesa_init_point, fix default user
- * settable max point size up
- */
- st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA);
- /* these are not queryable. Note that GL basically mandates a 1.0 minimum
- * for non-aa sizes, but we can go down to 0.0 for aa points.
- */
- c->MinPointSize = 1.0f;
- c->MinPointSizeAA = 0.0f;
-
- c->MaxTextureMaxAnisotropy
- = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY));
-
- c->MaxTextureLodBias
- = screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_LOD_BIAS);
-
- c->MaxDrawBuffers
- = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
- 1, MAX_DRAW_BUFFERS);
-
- /* Quads always follow GL provoking rules. */
- c->QuadsFollowProvokingVertexConvention = GL_FALSE;
-
- for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) {
- struct gl_shader_compiler_options *options =
- &st->ctx->ShaderCompilerOptions[sh];
- struct gl_program_constants *pc;
-
- switch (sh) {
- case PIPE_SHADER_FRAGMENT:
- pc = &c->FragmentProgram;
- break;
- case PIPE_SHADER_VERTEX:
- pc = &c->VertexProgram;
- break;
- case PIPE_SHADER_GEOMETRY:
- pc = &c->GeometryProgram;
- break;
- default:
- assert(0);
- continue;
- }
-
- pc->MaxNativeInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
- pc->MaxNativeAluInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS);
- pc->MaxNativeTexInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS);
- pc->MaxNativeTexIndirections = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS);
- pc->MaxNativeAttribs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS);
- pc->MaxNativeTemps = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS);
- pc->MaxNativeAddressRegs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ADDRS);
- pc->MaxNativeParameters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONSTS);
- pc->MaxUniformComponents = 4 * MIN2(pc->MaxNativeParameters, MAX_UNIFORMS);
-
- options->EmitNoNoise = TRUE;
-
- /* TODO: make these more fine-grained if anyone needs it */
- options->EmitNoIfs = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
- options->EmitNoLoops = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH);
- options->EmitNoFunctions = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
- options->EmitNoMainReturn = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES);
-
- options->EmitNoCont = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED);
-
- options->EmitNoIndirectInput = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR);
- options->EmitNoIndirectOutput = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR);
- options->EmitNoIndirectTemp = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR);
- options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh,
- PIPE_SHADER_CAP_INDIRECT_CONST_ADDR);
-
- if(options->EmitNoLoops)
- options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
- }
-
- /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs
- * and is set in MaxNativeAttribs. It's always 2 colors + N generic
- * attributes. The GLSL compiler never uses COLORn for varyings, so we
- * subtract the 2 colors to get the maximum number of varyings (generic
- * attributes) supported by a driver. */
- c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS) - 2;
- c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING);
-
- /* XXX we'll need a better query here someday */
- if (screen->get_param(screen, PIPE_CAP_GLSL)) {
- c->GLSLVersion = 120;
- }
-}
-
-
-/**
- * Use pipe_screen::get_param() to query PIPE_CAP_ values to determine
- * which GL extensions are supported.
- * Quite a few extensions are always supported because they are standard
- * features or can be built on top of other gallium features.
- * Some fine tuning may still be needed.
- */
-void st_init_extensions(struct st_context *st)
-{
- struct pipe_screen *screen = st->pipe->screen;
- struct gl_context *ctx = st->ctx;
-
- /*
- * Extensions that are supported by all Gallium drivers:
- */
- ctx->Extensions.ARB_copy_buffer = GL_TRUE;
- ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
- ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
- ctx->Extensions.ARB_fragment_program = GL_TRUE;
- ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
- ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
- ctx->Extensions.ARB_multisample = GL_TRUE;
- ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */
- ctx->Extensions.ARB_texture_compression = GL_TRUE;
- ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
- ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
- ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
- ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
- ctx->Extensions.ARB_vertex_array_object = GL_TRUE;
- ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
- ctx->Extensions.ARB_vertex_program = GL_TRUE;
- ctx->Extensions.ARB_window_pos = GL_TRUE;
-
- ctx->Extensions.EXT_blend_color = GL_TRUE;
- ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
- ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
- ctx->Extensions.EXT_blend_minmax = GL_TRUE;
- ctx->Extensions.EXT_blend_subtract = GL_TRUE;
- ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
- ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
- ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
- ctx->Extensions.EXT_fog_coord = GL_TRUE;
- ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
- ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
- ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
- ctx->Extensions.EXT_point_parameters = GL_TRUE;
- ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
- ctx->Extensions.EXT_secondary_color = GL_TRUE;
- ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
- ctx->Extensions.EXT_texture_env_add = GL_TRUE;
- ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
- ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
- ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
- ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
-
- ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
-
- ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
-
- ctx->Extensions.MESA_pack_invert = GL_TRUE;
-
- ctx->Extensions.NV_blend_square = GL_TRUE;
- ctx->Extensions.NV_texgen_reflection = GL_TRUE;
- ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
- ctx->Extensions.NV_texture_rectangle = GL_TRUE;
-#if 0
- /* possibly could support the following two */
- ctx->Extensions.NV_vertex_program = GL_TRUE;
- ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
-#endif
-
-#if FEATURE_OES_EGL_image
- ctx->Extensions.OES_EGL_image = GL_TRUE;
-#endif
-#if FEATURE_OES_draw_texture
- ctx->Extensions.OES_draw_texture = GL_TRUE;
-#endif
-
- ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
-
- /*
- * Extensions that depend on the driver/hardware:
- */
- if (screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS) > 0) {
- ctx->Extensions.ARB_draw_buffers = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_SWIZZLE) > 0) {
- ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_GLSL)) {
- ctx->Extensions.ARB_fragment_shader = GL_TRUE;
- ctx->Extensions.ARB_vertex_shader = GL_TRUE;
- ctx->Extensions.ARB_shader_objects = GL_TRUE;
- ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
- ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
- ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_REPEAT) > 0) {
- ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE)) {
- ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_CLAMP) > 0) {
- ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
- ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
- ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS) > 1) {
- ctx->Extensions.ARB_multitexture = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
- ctx->Extensions.ATI_separate_stencil = GL_TRUE;
- ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_ANISOTROPIC_FILTER)) {
- ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) {
- ctx->Extensions.ARB_point_sprite = GL_TRUE;
- /* GL_NV_point_sprite is not supported by gallium because we don't
- * support the GL_POINT_SPRITE_R_MODE_NV option.
- */
- }
-
- if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
- ctx->Extensions.ARB_occlusion_query = GL_TRUE;
- ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
- }
- if (screen->get_param(screen, PIPE_CAP_TIMER_QUERY)) {
- ctx->Extensions.EXT_timer_query = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_TEXTURE_SHADOW_MAP)) {
- ctx->Extensions.ARB_depth_texture = GL_TRUE;
- ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
- ctx->Extensions.ARB_shadow = GL_TRUE;
- ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
- /*ctx->Extensions.ARB_shadow_ambient = GL_TRUE;*/
- }
-
- /* GL_EXT_packed_depth_stencil requires both the ability to render to
- * a depth/stencil buffer and texture from depth/stencil source.
- */
- if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0) &&
- screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0)) {
- ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
- }
- else if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0) &&
- screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0)) {
- ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
- }
-
- /* sRGB support */
- if (screen->is_format_supported(screen, PIPE_FORMAT_A8B8G8R8_SRGB,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0) ||
- screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0)) {
- ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
- ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
- }
-
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0)) {
- ctx->Extensions.ARB_texture_rg = GL_TRUE;
- }
-
- /* s3tc support */
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0) &&
- (ctx->Mesa_DXTn ||
- screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0))) {
- ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
- ctx->Extensions.S3_s3tc = GL_TRUE;
- }
-
- /* ycbcr support */
- if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0) ||
- screen->is_format_supported(screen, PIPE_FORMAT_YUYV,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0)) {
- ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
- }
-
- /* GL_ARB_framebuffer_object */
- if (ctx->Extensions.EXT_packed_depth_stencil) {
- /* we support always support GL_EXT_framebuffer_blit */
- ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
- }
-
- if (st->pipe->render_condition) {
- ctx->Extensions.NV_conditional_render = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) {
- ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
- }
-
- /* GL_ARB_half_float_vertex */
- if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_BUFFER, 0,
- PIPE_BIND_VERTEX_BUFFER, 0)) {
- ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) {
- ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
- }
-
- if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
-#if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */
- ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
-#endif
- }
-
- if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
- ctx->Extensions.NV_primitive_restart = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
- ctx->Extensions.ARB_depth_clamp = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
- ctx->Extensions.ARB_shader_stencil_export = GL_TRUE;
- }
-
- if (screen->get_param(screen, PIPE_CAP_INSTANCED_DRAWING)) {
- ctx->Extensions.ARB_draw_instanced = GL_TRUE;
- ctx->Extensions.ARB_instanced_arrays = GL_TRUE;
- }
-}
+/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright (c) 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "main/imports.h" +#include "main/context.h" +#include "main/macros.h" +#include "main/mfeatures.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" + +#include "st_context.h" +#include "st_extensions.h" + + +static int _min(int a, int b) +{ + return (a < b) ? a : b; +} + +static float _maxf(float a, float b) +{ + return (a > b) ? a : b; +} + +static int _clamp(int a, int min, int max) +{ + if (a < min) + return min; + else if (a > max) + return max; + else + return a; +} + + +/** + * Query driver to get implementation limits. + * Note that we have to limit/clamp against Mesa's internal limits too. + */ +void st_init_limits(struct st_context *st) +{ + struct pipe_screen *screen = st->pipe->screen; + struct gl_constants *c = &st->ctx->Const; + gl_shader_type sh; + + c->MaxTextureLevels + = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), + MAX_TEXTURE_LEVELS); + + c->Max3DTextureLevels + = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS), + MAX_3D_TEXTURE_LEVELS); + + c->MaxCubeTextureLevels + = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS), + MAX_CUBE_TEXTURE_LEVELS); + + c->MaxTextureRectSize + = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE); + + c->MaxTextureImageUnits + = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS), + MAX_TEXTURE_IMAGE_UNITS); + + c->MaxVertexTextureImageUnits + = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS), + MAX_VERTEX_TEXTURE_IMAGE_UNITS); + + c->MaxCombinedTextureImageUnits + = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS), + MAX_COMBINED_TEXTURE_IMAGE_UNITS); + + c->MaxTextureCoordUnits + = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); + + c->MaxTextureUnits = _min(c->MaxTextureImageUnits, c->MaxTextureCoordUnits); + + c->MaxDrawBuffers + = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), + 1, MAX_DRAW_BUFFERS); + + c->MaxLineWidth + = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH)); + c->MaxLineWidthAA + = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH_AA)); + + c->MaxPointSize + = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH)); + c->MaxPointSizeAA + = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA)); + /* called after _mesa_create_context/_mesa_init_point, fix default user + * settable max point size up + */ + st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA); + /* these are not queryable. Note that GL basically mandates a 1.0 minimum + * for non-aa sizes, but we can go down to 0.0 for aa points. + */ + c->MinPointSize = 1.0f; + c->MinPointSizeAA = 0.0f; + + c->MaxTextureMaxAnisotropy + = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY)); + + c->MaxTextureLodBias + = screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_LOD_BIAS); + + c->MaxDrawBuffers + = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), + 1, MAX_DRAW_BUFFERS); + + /* Quads always follow GL provoking rules. */ + c->QuadsFollowProvokingVertexConvention = GL_FALSE; + + for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) { + struct gl_shader_compiler_options *options = + &st->ctx->ShaderCompilerOptions[sh]; + struct gl_program_constants *pc; + + switch (sh) { + case PIPE_SHADER_FRAGMENT: + pc = &c->FragmentProgram; + break; + case PIPE_SHADER_VERTEX: + pc = &c->VertexProgram; + break; + case PIPE_SHADER_GEOMETRY: + pc = &c->GeometryProgram; + break; + default: + assert(0); + continue; + } + + pc->MaxNativeInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS); + pc->MaxNativeAluInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS); + pc->MaxNativeTexInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS); + pc->MaxNativeTexIndirections = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS); + pc->MaxNativeAttribs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS); + pc->MaxNativeTemps = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS); + pc->MaxNativeAddressRegs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ADDRS); + pc->MaxNativeParameters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONSTS); + pc->MaxUniformComponents = 4 * MIN2(pc->MaxNativeParameters, MAX_UNIFORMS); + + options->EmitNoNoise = TRUE; + + /* TODO: make these more fine-grained if anyone needs it */ + options->EmitNoIfs = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); + options->EmitNoLoops = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); + options->EmitNoFunctions = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES); + options->EmitNoMainReturn = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES); + + options->EmitNoCont = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED); + + options->EmitNoIndirectInput = !screen->get_shader_param(screen, sh, + PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR); + options->EmitNoIndirectOutput = !screen->get_shader_param(screen, sh, + PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR); + options->EmitNoIndirectTemp = !screen->get_shader_param(screen, sh, + PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR); + options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh, + PIPE_SHADER_CAP_INDIRECT_CONST_ADDR); + + if(options->EmitNoLoops) + options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536); + } + + /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs + * and is set in MaxNativeAttribs. It's always 2 colors + N generic + * attributes. The GLSL compiler never uses COLORn for varyings, so we + * subtract the 2 colors to get the maximum number of varyings (generic + * attributes) supported by a driver. */ + c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS) - 2; + c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING); + + /* XXX we'll need a better query here someday */ + if (screen->get_param(screen, PIPE_CAP_GLSL)) { + c->GLSLVersion = 120; + } +} + + +/** + * Use pipe_screen::get_param() to query PIPE_CAP_ values to determine + * which GL extensions are supported. + * Quite a few extensions are always supported because they are standard + * features or can be built on top of other gallium features. + * Some fine tuning may still be needed. + */ +void st_init_extensions(struct st_context *st) +{ + struct pipe_screen *screen = st->pipe->screen; + struct gl_context *ctx = st->ctx; + + /* + * Extensions that are supported by all Gallium drivers: + */ + ctx->Extensions.ARB_copy_buffer = GL_TRUE; + ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE; + ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; + ctx->Extensions.ARB_fragment_program = GL_TRUE; + ctx->Extensions.ARB_half_float_pixel = GL_TRUE; + ctx->Extensions.ARB_map_buffer_range = GL_TRUE; + ctx->Extensions.ARB_multisample = GL_TRUE; + ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */ + ctx->Extensions.ARB_texture_compression = GL_TRUE; + ctx->Extensions.ARB_texture_cube_map = GL_TRUE; + ctx->Extensions.ARB_texture_env_combine = GL_TRUE; + ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE; + ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE; + ctx->Extensions.ARB_vertex_array_object = GL_TRUE; + ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE; + ctx->Extensions.ARB_vertex_program = GL_TRUE; + ctx->Extensions.ARB_window_pos = GL_TRUE; + + ctx->Extensions.EXT_blend_color = GL_TRUE; + ctx->Extensions.EXT_blend_func_separate = GL_TRUE; + ctx->Extensions.EXT_blend_logic_op = GL_TRUE; + ctx->Extensions.EXT_blend_minmax = GL_TRUE; + ctx->Extensions.EXT_blend_subtract = GL_TRUE; + ctx->Extensions.EXT_framebuffer_blit = GL_TRUE; + ctx->Extensions.EXT_framebuffer_object = GL_TRUE; + ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE; + ctx->Extensions.EXT_fog_coord = GL_TRUE; + ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE; + ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE; + ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE; + ctx->Extensions.EXT_point_parameters = GL_TRUE; + ctx->Extensions.EXT_provoking_vertex = GL_TRUE; + ctx->Extensions.EXT_secondary_color = GL_TRUE; + ctx->Extensions.EXT_stencil_wrap = GL_TRUE; + ctx->Extensions.EXT_texture_env_add = GL_TRUE; + ctx->Extensions.EXT_texture_env_combine = GL_TRUE; + ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; + ctx->Extensions.EXT_texture_lod_bias = GL_TRUE; + ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE; + + ctx->Extensions.APPLE_vertex_array_object = GL_TRUE; + + ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE; + + ctx->Extensions.MESA_pack_invert = GL_TRUE; + + ctx->Extensions.NV_blend_square = GL_TRUE; + ctx->Extensions.NV_texgen_reflection = GL_TRUE; + ctx->Extensions.NV_texture_env_combine4 = GL_TRUE; + ctx->Extensions.NV_texture_rectangle = GL_TRUE; +#if 0 + /* possibly could support the following two */ + ctx->Extensions.NV_vertex_program = GL_TRUE; + ctx->Extensions.NV_vertex_program1_1 = GL_TRUE; +#endif + +#if FEATURE_OES_EGL_image + ctx->Extensions.OES_EGL_image = GL_TRUE; +#endif +#if FEATURE_OES_draw_texture + ctx->Extensions.OES_draw_texture = GL_TRUE; +#endif + + ctx->Extensions.SGIS_generate_mipmap = GL_TRUE; + + /* + * Extensions that depend on the driver/hardware: + */ + if (screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS) > 0) { + ctx->Extensions.ARB_draw_buffers = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_TEXTURE_SWIZZLE) > 0) { + ctx->Extensions.EXT_texture_swizzle = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_GLSL)) { + ctx->Extensions.ARB_fragment_shader = GL_TRUE; + ctx->Extensions.ARB_vertex_shader = GL_TRUE; + ctx->Extensions.ARB_shader_objects = GL_TRUE; + ctx->Extensions.ARB_shading_language_100 = GL_TRUE; + ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE; + ctx->Extensions.EXT_separate_shader_objects = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_REPEAT) > 0) { + ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE)) { + ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_CLAMP) > 0) { + ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE; + ctx->Extensions.ATI_texture_mirror_once = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) { + ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS) > 1) { + ctx->Extensions.ARB_multitexture = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) { + ctx->Extensions.ATI_separate_stencil = GL_TRUE; + ctx->Extensions.EXT_stencil_two_side = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_ANISOTROPIC_FILTER)) { + ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) { + ctx->Extensions.ARB_point_sprite = GL_TRUE; + /* GL_NV_point_sprite is not supported by gallium because we don't + * support the GL_POINT_SPRITE_R_MODE_NV option. + */ + } + + if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) { + ctx->Extensions.ARB_occlusion_query = GL_TRUE; + ctx->Extensions.ARB_occlusion_query2 = GL_TRUE; + } + if (screen->get_param(screen, PIPE_CAP_TIMER_QUERY)) { + ctx->Extensions.EXT_timer_query = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_TEXTURE_SHADOW_MAP)) { + ctx->Extensions.ARB_depth_texture = GL_TRUE; + ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE; + ctx->Extensions.ARB_shadow = GL_TRUE; + ctx->Extensions.EXT_shadow_funcs = GL_TRUE; + /*ctx->Extensions.ARB_shadow_ambient = GL_TRUE;*/ + } + + /* GL_EXT_packed_depth_stencil requires both the ability to render to + * a depth/stencil buffer and texture from depth/stencil source. + */ + if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_DEPTH_STENCIL, 0) && + screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0)) { + ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE; + } + else if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_DEPTH_STENCIL, 0) && + screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0)) { + ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE; + } + + /* sRGB support */ + if (screen->is_format_supported(screen, PIPE_FORMAT_A8B8G8R8_SRGB, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0) || + screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0)) { + ctx->Extensions.EXT_texture_sRGB = GL_TRUE; + ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE; + } + + if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0)) { + ctx->Extensions.ARB_texture_rg = GL_TRUE; + } + + /* s3tc support */ + if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0) && + (ctx->Mesa_DXTn || + screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_RENDER_TARGET, 0))) { + ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE; + ctx->Extensions.S3_s3tc = GL_TRUE; + } + + /* ycbcr support */ + if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0) || + screen->is_format_supported(screen, PIPE_FORMAT_YUYV, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW, 0)) { + ctx->Extensions.MESA_ycbcr_texture = GL_TRUE; + } + + /* GL_ARB_framebuffer_object */ + if (ctx->Extensions.EXT_packed_depth_stencil) { + /* we support always support GL_EXT_framebuffer_blit */ + ctx->Extensions.ARB_framebuffer_object = GL_TRUE; + } + + if (st->pipe->render_condition) { + ctx->Extensions.NV_conditional_render = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) { + ctx->Extensions.EXT_draw_buffers2 = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) { + ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE; + } + + /* GL_ARB_half_float_vertex */ + if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_BUFFER, 0, + PIPE_BIND_VERTEX_BUFFER, 0)) { + ctx->Extensions.ARB_half_float_vertex = GL_TRUE; + } + + if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { +#if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */ + ctx->Extensions.ARB_geometry_shader4 = GL_TRUE; +#endif + } + + if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) { + ctx->Extensions.NV_primitive_restart = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) { + ctx->Extensions.ARB_depth_clamp = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) { + ctx->Extensions.ARB_shader_stencil_export = GL_TRUE; + } + + if (screen->get_param(screen, PIPE_CAP_INSTANCED_DRAWING)) { + ctx->Extensions.ARB_draw_instanced = GL_TRUE; + ctx->Extensions.ARB_instanced_arrays = GL_TRUE; + } +} diff --git a/mesalib/src/mesa/vbo/vbo_split_copy.c b/mesalib/src/mesa/vbo/vbo_split_copy.c index e172da08b..8c981f93e 100644 --- a/mesalib/src/mesa/vbo/vbo_split_copy.c +++ b/mesalib/src/mesa/vbo/vbo_split_copy.c @@ -1,625 +1,626 @@ -
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-/* Split indexed primitives with per-vertex copying.
- */
-
-#include "main/glheader.h"
-#include "main/bufferobj.h"
-#include "main/imports.h"
-#include "main/image.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-
-#include "vbo_split.h"
-#include "vbo.h"
-
-
-#define ELT_TABLE_SIZE 16
-
-/**
- * Used for vertex-level splitting of indexed buffers. Note that
- * non-indexed primitives may be converted to indexed in some cases
- * (eg loops, fans) in order to use this splitting path.
- */
-struct copy_context {
-
- struct gl_context *ctx;
- const struct gl_client_array **array;
- const struct _mesa_prim *prim;
- GLuint nr_prims;
- const struct _mesa_index_buffer *ib;
- vbo_draw_func draw;
-
- const struct split_limits *limits;
-
- struct {
- GLuint attr;
- GLuint size;
- const struct gl_client_array *array;
- const GLubyte *src_ptr;
-
- struct gl_client_array dstarray;
-
- } varying[VERT_ATTRIB_MAX];
- GLuint nr_varying;
-
- const struct gl_client_array *dstarray_ptr[VERT_ATTRIB_MAX];
- struct _mesa_index_buffer dstib;
-
- GLuint *translated_elt_buf;
- const GLuint *srcelt;
-
- /** A baby hash table to avoid re-emitting (some) duplicate
- * vertices when splitting indexed primitives.
- */
- struct {
- GLuint in;
- GLuint out;
- } vert_cache[ELT_TABLE_SIZE];
-
- GLuint vertex_size;
- GLubyte *dstbuf;
- GLubyte *dstptr; /**< dstptr == dstbuf + dstelt_max * vertsize */
- GLuint dstbuf_size; /**< in vertices */
- GLuint dstbuf_nr; /**< count of emitted vertices, also the largest value
- * in dstelt. Our MaxIndex.
- */
-
- GLuint *dstelt;
- GLuint dstelt_nr;
- GLuint dstelt_size;
-
-#define MAX_PRIM 32
- struct _mesa_prim dstprim[MAX_PRIM];
- GLuint dstprim_nr;
-
-};
-
-
-static GLuint attr_size( const struct gl_client_array *array )
-{
- return array->Size * _mesa_sizeof_type(array->Type);
-}
-
-
-/**
- * Starts returning true slightly before the buffer fills, to ensure
- * that there is sufficient room for any remaining vertices to finish
- * off the prim:
- */
-static GLboolean
-check_flush( struct copy_context *copy )
-{
- GLenum mode = copy->dstprim[copy->dstprim_nr].mode;
-
- if (GL_TRIANGLE_STRIP == mode &&
- copy->dstelt_nr & 1) { /* see bug9962 */
- return GL_FALSE;
- }
-
- if (copy->dstbuf_nr + 4 > copy->dstbuf_size)
- return GL_TRUE;
-
- if (copy->dstelt_nr + 4 > copy->dstelt_size)
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-/**
- * Dump the parameters/info for a vbo->draw() call.
- */
-static void
-dump_draw_info(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- const struct _mesa_prim *prims,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLuint min_index,
- GLuint max_index)
-{
- GLuint i, j;
-
- printf("VBO Draw:\n");
- for (i = 0; i < nr_prims; i++) {
- printf("Prim %u of %u\n", i, nr_prims);
- printf(" Prim mode 0x%x\n", prims[i].mode);
- printf(" IB: %p\n", (void*) ib);
- for (j = 0; j < VERT_ATTRIB_MAX; j++) {
- printf(" array %d at %p:\n", j, (void*) arrays[j]);
- printf(" enabled %d, ptr %p, size %d, type 0x%x, stride %d\n",
- arrays[j]->Enabled, arrays[j]->Ptr,
- arrays[j]->Size, arrays[j]->Type, arrays[j]->StrideB);
- if (0) {
- GLint k = prims[i].start + prims[i].count - 1;
- GLfloat *last = (GLfloat *) (arrays[j]->Ptr + arrays[j]->Stride * k);
- printf(" last: %f %f %f\n",
- last[0], last[1], last[2]);
- }
- }
- }
-}
-
-
-static void
-flush( struct copy_context *copy )
-{
- GLuint i;
-
- /* Set some counters:
- */
- copy->dstib.count = copy->dstelt_nr;
-
-#if 0
- dump_draw_info(copy->ctx,
- copy->dstarray_ptr,
- copy->dstprim,
- copy->dstprim_nr,
- ©->dstib,
- 0,
- copy->dstbuf_nr);
-#else
- (void) dump_draw_info;
-#endif
-
- copy->draw( copy->ctx,
- copy->dstarray_ptr,
- copy->dstprim,
- copy->dstprim_nr,
- ©->dstib,
- GL_TRUE,
- 0,
- copy->dstbuf_nr - 1 );
-
- /* Reset all pointers:
- */
- copy->dstprim_nr = 0;
- copy->dstelt_nr = 0;
- copy->dstbuf_nr = 0;
- copy->dstptr = copy->dstbuf;
-
- /* Clear the vertex cache:
- */
- for (i = 0; i < ELT_TABLE_SIZE; i++)
- copy->vert_cache[i].in = ~0;
-}
-
-
-/**
- * Called at begin of each primitive during replay.
- */
-static void
-begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag )
-{
- struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr];
-
- prim->mode = mode;
- prim->begin = begin_flag;
-}
-
-
-/**
- * Use a hashtable to attempt to identify recently-emitted vertices
- * and avoid re-emitting them.
- */
-static GLuint
-elt(struct copy_context *copy, GLuint elt_idx)
-{
- GLuint elt = copy->srcelt[elt_idx];
- GLuint slot = elt & (ELT_TABLE_SIZE-1);
-
-/* printf("elt %d\n", elt); */
-
- /* Look up the incoming element in the vertex cache. Re-emit if
- * necessary.
- */
- if (copy->vert_cache[slot].in != elt) {
- GLubyte *csr = copy->dstptr;
- GLuint i;
-
-/* printf(" --> emit to dstelt %d\n", copy->dstbuf_nr); */
-
- for (i = 0; i < copy->nr_varying; i++) {
- const struct gl_client_array *srcarray = copy->varying[i].array;
- const GLubyte *srcptr = copy->varying[i].src_ptr + elt * srcarray->StrideB;
-
- memcpy(csr, srcptr, copy->varying[i].size);
- csr += copy->varying[i].size;
-
-#ifdef NAN_CHECK
- if (srcarray->Type == GL_FLOAT) {
- GLuint k;
- GLfloat *f = (GLfloat *) srcptr;
- for (k = 0; k < srcarray->Size; k++) {
- assert(!IS_INF_OR_NAN(f[k]));
- assert(f[k] <= 1.0e20 && f[k] >= -1.0e20);
- }
- }
-#endif
-
- if (0)
- {
- const GLuint *f = (const GLuint *)srcptr;
- GLuint j;
- printf(" varying %d: ", i);
- for(j = 0; j < copy->varying[i].size / 4; j++)
- printf("%x ", f[j]);
- printf("\n");
- }
- }
-
- copy->vert_cache[slot].in = elt;
- copy->vert_cache[slot].out = copy->dstbuf_nr++;
- copy->dstptr += copy->vertex_size;
-
- assert(csr == copy->dstptr);
- assert(copy->dstptr == (copy->dstbuf +
- copy->dstbuf_nr * copy->vertex_size));
- }
-/* else */
-/* printf(" --> reuse vertex\n"); */
-
-/* printf(" --> emit %d\n", copy->vert_cache[slot].out); */
- copy->dstelt[copy->dstelt_nr++] = copy->vert_cache[slot].out;
- return check_flush(copy);
-}
-
-
-/**
- * Called at end of each primitive during replay.
- */
-static void
-end( struct copy_context *copy, GLboolean end_flag )
-{
- struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr];
-
-/* printf("end (%d)\n", end_flag); */
-
- prim->end = end_flag;
- prim->count = copy->dstelt_nr - prim->start;
-
- if (++copy->dstprim_nr == MAX_PRIM ||
- check_flush(copy))
- flush(copy);
-}
-
-
-static void
-replay_elts( struct copy_context *copy )
-{
- GLuint i, j, k;
- GLboolean split;
-
- for (i = 0; i < copy->nr_prims; i++) {
- const struct _mesa_prim *prim = ©->prim[i];
- const GLuint start = prim->start;
- GLuint first, incr;
-
- switch (prim->mode) {
-
- case GL_LINE_LOOP:
- /* Convert to linestrip and emit the final vertex explicitly,
- * but only in the resultant strip that requires it.
- */
- j = 0;
- while (j != prim->count) {
- begin(copy, GL_LINE_STRIP, prim->begin && j == 0);
-
- for (split = GL_FALSE; j != prim->count && !split; j++)
- split = elt(copy, start + j);
-
- if (j == prim->count) {
- /* Done, emit final line. Split doesn't matter as
- * it is always raised a bit early so we can emit
- * the last verts if necessary!
- */
- if (prim->end)
- (void)elt(copy, start + 0);
-
- end(copy, prim->end);
- }
- else {
- /* Wrap
- */
- assert(split);
- end(copy, 0);
- j--;
- }
- }
- break;
-
- case GL_TRIANGLE_FAN:
- case GL_POLYGON:
- j = 2;
- while (j != prim->count) {
- begin(copy, prim->mode, prim->begin && j == 0);
-
- split = elt(copy, start+0);
- assert(!split);
-
- split = elt(copy, start+j-1);
- assert(!split);
-
- for (; j != prim->count && !split; j++)
- split = elt(copy, start+j);
-
- end(copy, prim->end && j == prim->count);
-
- if (j != prim->count) {
- /* Wrapped the primitive, need to repeat some vertices:
- */
- j -= 1;
- }
- }
- break;
-
- default:
- (void)split_prim_inplace(prim->mode, &first, &incr);
-
- j = 0;
- while (j != prim->count) {
-
- begin(copy, prim->mode, prim->begin && j == 0);
-
- split = 0;
- for (k = 0; k < first; k++, j++)
- split |= elt(copy, start+j);
-
- assert(!split);
-
- for (; j != prim->count && !split; )
- for (k = 0; k < incr; k++, j++)
- split |= elt(copy, start+j);
-
- end(copy, prim->end && j == prim->count);
-
- if (j != prim->count) {
- /* Wrapped the primitive, need to repeat some vertices:
- */
- assert(j > first - incr);
- j -= (first - incr);
- }
- }
- break;
- }
- }
-
- if (copy->dstprim_nr)
- flush(copy);
-}
-
-
-static void
-replay_init( struct copy_context *copy )
-{
- struct gl_context *ctx = copy->ctx;
- GLuint i;
- GLuint offset;
- const GLvoid *srcptr;
-
- /* Make a list of varying attributes and their vbo's. Also
- * calculate vertex size.
- */
- copy->vertex_size = 0;
- for (i = 0; i < VERT_ATTRIB_MAX; i++) {
- struct gl_buffer_object *vbo = copy->array[i]->BufferObj;
-
- if (copy->array[i]->StrideB == 0) {
- copy->dstarray_ptr[i] = copy->array[i];
- }
- else {
- GLuint j = copy->nr_varying++;
-
- copy->varying[j].attr = i;
- copy->varying[j].array = copy->array[i];
- copy->varying[j].size = attr_size(copy->array[i]);
- copy->vertex_size += attr_size(copy->array[i]);
-
- if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo))
- ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY, vbo);
-
- copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer,
- copy->array[i]->Ptr);
-
- copy->dstarray_ptr[i] = ©->varying[j].dstarray;
- }
- }
-
- /* There must always be an index buffer. Currently require the
- * caller convert non-indexed prims to indexed. Could alternately
- * do it internally.
- */
- if (_mesa_is_bufferobj(copy->ib->obj) &&
- !_mesa_bufferobj_mapped(copy->ib->obj))
- ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY,
- copy->ib->obj);
-
- srcptr = (const GLubyte *) ADD_POINTERS(copy->ib->obj->Pointer,
- copy->ib->ptr);
-
- switch (copy->ib->type) {
- case GL_UNSIGNED_BYTE:
- copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count);
- copy->srcelt = copy->translated_elt_buf;
-
- for (i = 0; i < copy->ib->count; i++)
- copy->translated_elt_buf[i] = ((const GLubyte *)srcptr)[i];
- break;
-
- case GL_UNSIGNED_SHORT:
- copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count);
- copy->srcelt = copy->translated_elt_buf;
-
- for (i = 0; i < copy->ib->count; i++)
- copy->translated_elt_buf[i] = ((const GLushort *)srcptr)[i];
- break;
-
- case GL_UNSIGNED_INT:
- copy->translated_elt_buf = NULL;
- copy->srcelt = (const GLuint *)srcptr;
- break;
- }
-
- /* Figure out the maximum allowed vertex buffer size:
- */
- if (copy->vertex_size * copy->limits->max_verts <= copy->limits->max_vb_size) {
- copy->dstbuf_size = copy->limits->max_verts;
- }
- else {
- copy->dstbuf_size = copy->limits->max_vb_size / copy->vertex_size;
- }
-
- /* Allocate an output vertex buffer:
- *
- * XXX: This should be a VBO!
- */
- copy->dstbuf = malloc(copy->dstbuf_size * copy->vertex_size);
- copy->dstptr = copy->dstbuf;
-
- /* Setup new vertex arrays to point into the output buffer:
- */
- for (offset = 0, i = 0; i < copy->nr_varying; i++) {
- const struct gl_client_array *src = copy->varying[i].array;
- struct gl_client_array *dst = ©->varying[i].dstarray;
-
- dst->Size = src->Size;
- dst->Type = src->Type;
- dst->Format = GL_RGBA;
- dst->Stride = copy->vertex_size;
- dst->StrideB = copy->vertex_size;
- dst->Ptr = copy->dstbuf + offset;
- dst->Enabled = GL_TRUE;
- dst->Normalized = src->Normalized;
- dst->BufferObj = ctx->Shared->NullBufferObj;
- dst->_MaxElement = copy->dstbuf_size; /* may be less! */
-
- offset += copy->varying[i].size;
- }
-
- /* Allocate an output element list:
- */
- copy->dstelt_size = MIN2(65536,
- copy->ib->count * 2 + 3);
- copy->dstelt_size = MIN2(copy->dstelt_size,
- copy->limits->max_indices);
- copy->dstelt = malloc(sizeof(GLuint) * copy->dstelt_size);
- copy->dstelt_nr = 0;
-
- /* Setup the new index buffer to point to the allocated element
- * list:
- */
- copy->dstib.count = 0; /* duplicates dstelt_nr */
- copy->dstib.type = GL_UNSIGNED_INT;
- copy->dstib.obj = ctx->Shared->NullBufferObj;
- copy->dstib.ptr = copy->dstelt;
-}
-
-
-/**
- * Free up everything allocated during split/replay.
- */
-static void
-replay_finish( struct copy_context *copy )
-{
- struct gl_context *ctx = copy->ctx;
- GLuint i;
-
- /* Free our vertex and index buffers:
- */
- free(copy->translated_elt_buf);
- free(copy->dstbuf);
- free(copy->dstelt);
-
- /* Unmap VBO's
- */
- for (i = 0; i < copy->nr_varying; i++) {
- struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj;
- if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo))
- ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, vbo);
- }
-
- /* Unmap index buffer:
- */
- if (_mesa_is_bufferobj(copy->ib->obj) &&
- _mesa_bufferobj_mapped(copy->ib->obj)) {
- ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, copy->ib->obj);
- }
-}
-
-
-/**
- * Split VBO into smaller pieces, draw the pieces.
- */
-void vbo_split_copy( struct gl_context *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_prim *prim,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- vbo_draw_func draw,
- const struct split_limits *limits )
-{
- struct copy_context copy;
- GLuint i, this_nr_prims;
-
- for (i = 0; i < nr_prims;) {
- /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
- * will rebase the elements to the basevertex, and we'll only
- * emit strings of prims with the same basevertex in one draw call.
- */
- for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
- this_nr_prims++) {
- if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
- break;
- }
-
- memset(©, 0, sizeof(copy));
-
- /* Require indexed primitives:
- */
- assert(ib);
-
- copy.ctx = ctx;
- copy.array = arrays;
- copy.prim = &prim[i];
- copy.nr_prims = this_nr_prims;
- copy.ib = ib;
- copy.draw = draw;
- copy.limits = limits;
-
- /* Clear the vertex cache:
- */
- for (i = 0; i < ELT_TABLE_SIZE; i++)
- copy.vert_cache[i].in = ~0;
-
- replay_init(©);
- replay_elts(©);
- replay_finish(©);
- }
-}
+ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +/* Split indexed primitives with per-vertex copying. + */ + +#include "main/glheader.h" +#include "main/bufferobj.h" +#include "main/imports.h" +#include "main/image.h" +#include "main/macros.h" +#include "main/mtypes.h" + +#include "vbo_split.h" +#include "vbo.h" + + +#define ELT_TABLE_SIZE 16 + +/** + * Used for vertex-level splitting of indexed buffers. Note that + * non-indexed primitives may be converted to indexed in some cases + * (eg loops, fans) in order to use this splitting path. + */ +struct copy_context { + + struct gl_context *ctx; + const struct gl_client_array **array; + const struct _mesa_prim *prim; + GLuint nr_prims; + const struct _mesa_index_buffer *ib; + vbo_draw_func draw; + + const struct split_limits *limits; + + struct { + GLuint attr; + GLuint size; + const struct gl_client_array *array; + const GLubyte *src_ptr; + + struct gl_client_array dstarray; + + } varying[VERT_ATTRIB_MAX]; + GLuint nr_varying; + + const struct gl_client_array *dstarray_ptr[VERT_ATTRIB_MAX]; + struct _mesa_index_buffer dstib; + + GLuint *translated_elt_buf; + const GLuint *srcelt; + + /** A baby hash table to avoid re-emitting (some) duplicate + * vertices when splitting indexed primitives. + */ + struct { + GLuint in; + GLuint out; + } vert_cache[ELT_TABLE_SIZE]; + + GLuint vertex_size; + GLubyte *dstbuf; + GLubyte *dstptr; /**< dstptr == dstbuf + dstelt_max * vertsize */ + GLuint dstbuf_size; /**< in vertices */ + GLuint dstbuf_nr; /**< count of emitted vertices, also the largest value + * in dstelt. Our MaxIndex. + */ + + GLuint *dstelt; + GLuint dstelt_nr; + GLuint dstelt_size; + +#define MAX_PRIM 32 + struct _mesa_prim dstprim[MAX_PRIM]; + GLuint dstprim_nr; + +}; + + +static GLuint attr_size( const struct gl_client_array *array ) +{ + return array->Size * _mesa_sizeof_type(array->Type); +} + + +/** + * Starts returning true slightly before the buffer fills, to ensure + * that there is sufficient room for any remaining vertices to finish + * off the prim: + */ +static GLboolean +check_flush( struct copy_context *copy ) +{ + GLenum mode = copy->dstprim[copy->dstprim_nr].mode; + + if (GL_TRIANGLE_STRIP == mode && + copy->dstelt_nr & 1) { /* see bug9962 */ + return GL_FALSE; + } + + if (copy->dstbuf_nr + 4 > copy->dstbuf_size) + return GL_TRUE; + + if (copy->dstelt_nr + 4 > copy->dstelt_size) + return GL_TRUE; + + return GL_FALSE; +} + + +/** + * Dump the parameters/info for a vbo->draw() call. + */ +static void +dump_draw_info(struct gl_context *ctx, + const struct gl_client_array **arrays, + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index) +{ + GLuint i, j; + + printf("VBO Draw:\n"); + for (i = 0; i < nr_prims; i++) { + printf("Prim %u of %u\n", i, nr_prims); + printf(" Prim mode 0x%x\n", prims[i].mode); + printf(" IB: %p\n", (void*) ib); + for (j = 0; j < VERT_ATTRIB_MAX; j++) { + printf(" array %d at %p:\n", j, (void*) arrays[j]); + printf(" enabled %d, ptr %p, size %d, type 0x%x, stride %d\n", + arrays[j]->Enabled, arrays[j]->Ptr, + arrays[j]->Size, arrays[j]->Type, arrays[j]->StrideB); + if (0) { + GLint k = prims[i].start + prims[i].count - 1; + GLfloat *last = (GLfloat *) (arrays[j]->Ptr + arrays[j]->Stride * k); + printf(" last: %f %f %f\n", + last[0], last[1], last[2]); + } + } + } +} + + +static void +flush( struct copy_context *copy ) +{ + GLuint i; + + /* Set some counters: + */ + copy->dstib.count = copy->dstelt_nr; + +#if 0 + dump_draw_info(copy->ctx, + copy->dstarray_ptr, + copy->dstprim, + copy->dstprim_nr, + ©->dstib, + 0, + copy->dstbuf_nr); +#else + (void) dump_draw_info; +#endif + + copy->draw( copy->ctx, + copy->dstarray_ptr, + copy->dstprim, + copy->dstprim_nr, + ©->dstib, + GL_TRUE, + 0, + copy->dstbuf_nr - 1 ); + + /* Reset all pointers: + */ + copy->dstprim_nr = 0; + copy->dstelt_nr = 0; + copy->dstbuf_nr = 0; + copy->dstptr = copy->dstbuf; + + /* Clear the vertex cache: + */ + for (i = 0; i < ELT_TABLE_SIZE; i++) + copy->vert_cache[i].in = ~0; +} + + +/** + * Called at begin of each primitive during replay. + */ +static void +begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag ) +{ + struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; + + prim->mode = mode; + prim->begin = begin_flag; + prim->num_instances = 1; +} + + +/** + * Use a hashtable to attempt to identify recently-emitted vertices + * and avoid re-emitting them. + */ +static GLuint +elt(struct copy_context *copy, GLuint elt_idx) +{ + GLuint elt = copy->srcelt[elt_idx]; + GLuint slot = elt & (ELT_TABLE_SIZE-1); + +/* printf("elt %d\n", elt); */ + + /* Look up the incoming element in the vertex cache. Re-emit if + * necessary. + */ + if (copy->vert_cache[slot].in != elt) { + GLubyte *csr = copy->dstptr; + GLuint i; + +/* printf(" --> emit to dstelt %d\n", copy->dstbuf_nr); */ + + for (i = 0; i < copy->nr_varying; i++) { + const struct gl_client_array *srcarray = copy->varying[i].array; + const GLubyte *srcptr = copy->varying[i].src_ptr + elt * srcarray->StrideB; + + memcpy(csr, srcptr, copy->varying[i].size); + csr += copy->varying[i].size; + +#ifdef NAN_CHECK + if (srcarray->Type == GL_FLOAT) { + GLuint k; + GLfloat *f = (GLfloat *) srcptr; + for (k = 0; k < srcarray->Size; k++) { + assert(!IS_INF_OR_NAN(f[k])); + assert(f[k] <= 1.0e20 && f[k] >= -1.0e20); + } + } +#endif + + if (0) + { + const GLuint *f = (const GLuint *)srcptr; + GLuint j; + printf(" varying %d: ", i); + for(j = 0; j < copy->varying[i].size / 4; j++) + printf("%x ", f[j]); + printf("\n"); + } + } + + copy->vert_cache[slot].in = elt; + copy->vert_cache[slot].out = copy->dstbuf_nr++; + copy->dstptr += copy->vertex_size; + + assert(csr == copy->dstptr); + assert(copy->dstptr == (copy->dstbuf + + copy->dstbuf_nr * copy->vertex_size)); + } +/* else */ +/* printf(" --> reuse vertex\n"); */ + +/* printf(" --> emit %d\n", copy->vert_cache[slot].out); */ + copy->dstelt[copy->dstelt_nr++] = copy->vert_cache[slot].out; + return check_flush(copy); +} + + +/** + * Called at end of each primitive during replay. + */ +static void +end( struct copy_context *copy, GLboolean end_flag ) +{ + struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; + +/* printf("end (%d)\n", end_flag); */ + + prim->end = end_flag; + prim->count = copy->dstelt_nr - prim->start; + + if (++copy->dstprim_nr == MAX_PRIM || + check_flush(copy)) + flush(copy); +} + + +static void +replay_elts( struct copy_context *copy ) +{ + GLuint i, j, k; + GLboolean split; + + for (i = 0; i < copy->nr_prims; i++) { + const struct _mesa_prim *prim = ©->prim[i]; + const GLuint start = prim->start; + GLuint first, incr; + + switch (prim->mode) { + + case GL_LINE_LOOP: + /* Convert to linestrip and emit the final vertex explicitly, + * but only in the resultant strip that requires it. + */ + j = 0; + while (j != prim->count) { + begin(copy, GL_LINE_STRIP, prim->begin && j == 0); + + for (split = GL_FALSE; j != prim->count && !split; j++) + split = elt(copy, start + j); + + if (j == prim->count) { + /* Done, emit final line. Split doesn't matter as + * it is always raised a bit early so we can emit + * the last verts if necessary! + */ + if (prim->end) + (void)elt(copy, start + 0); + + end(copy, prim->end); + } + else { + /* Wrap + */ + assert(split); + end(copy, 0); + j--; + } + } + break; + + case GL_TRIANGLE_FAN: + case GL_POLYGON: + j = 2; + while (j != prim->count) { + begin(copy, prim->mode, prim->begin && j == 0); + + split = elt(copy, start+0); + assert(!split); + + split = elt(copy, start+j-1); + assert(!split); + + for (; j != prim->count && !split; j++) + split = elt(copy, start+j); + + end(copy, prim->end && j == prim->count); + + if (j != prim->count) { + /* Wrapped the primitive, need to repeat some vertices: + */ + j -= 1; + } + } + break; + + default: + (void)split_prim_inplace(prim->mode, &first, &incr); + + j = 0; + while (j != prim->count) { + + begin(copy, prim->mode, prim->begin && j == 0); + + split = 0; + for (k = 0; k < first; k++, j++) + split |= elt(copy, start+j); + + assert(!split); + + for (; j != prim->count && !split; ) + for (k = 0; k < incr; k++, j++) + split |= elt(copy, start+j); + + end(copy, prim->end && j == prim->count); + + if (j != prim->count) { + /* Wrapped the primitive, need to repeat some vertices: + */ + assert(j > first - incr); + j -= (first - incr); + } + } + break; + } + } + + if (copy->dstprim_nr) + flush(copy); +} + + +static void +replay_init( struct copy_context *copy ) +{ + struct gl_context *ctx = copy->ctx; + GLuint i; + GLuint offset; + const GLvoid *srcptr; + + /* Make a list of varying attributes and their vbo's. Also + * calculate vertex size. + */ + copy->vertex_size = 0; + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + struct gl_buffer_object *vbo = copy->array[i]->BufferObj; + + if (copy->array[i]->StrideB == 0) { + copy->dstarray_ptr[i] = copy->array[i]; + } + else { + GLuint j = copy->nr_varying++; + + copy->varying[j].attr = i; + copy->varying[j].array = copy->array[i]; + copy->varying[j].size = attr_size(copy->array[i]); + copy->vertex_size += attr_size(copy->array[i]); + + if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo)) + ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY, vbo); + + copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer, + copy->array[i]->Ptr); + + copy->dstarray_ptr[i] = ©->varying[j].dstarray; + } + } + + /* There must always be an index buffer. Currently require the + * caller convert non-indexed prims to indexed. Could alternately + * do it internally. + */ + if (_mesa_is_bufferobj(copy->ib->obj) && + !_mesa_bufferobj_mapped(copy->ib->obj)) + ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY, + copy->ib->obj); + + srcptr = (const GLubyte *) ADD_POINTERS(copy->ib->obj->Pointer, + copy->ib->ptr); + + switch (copy->ib->type) { + case GL_UNSIGNED_BYTE: + copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); + copy->srcelt = copy->translated_elt_buf; + + for (i = 0; i < copy->ib->count; i++) + copy->translated_elt_buf[i] = ((const GLubyte *)srcptr)[i]; + break; + + case GL_UNSIGNED_SHORT: + copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); + copy->srcelt = copy->translated_elt_buf; + + for (i = 0; i < copy->ib->count; i++) + copy->translated_elt_buf[i] = ((const GLushort *)srcptr)[i]; + break; + + case GL_UNSIGNED_INT: + copy->translated_elt_buf = NULL; + copy->srcelt = (const GLuint *)srcptr; + break; + } + + /* Figure out the maximum allowed vertex buffer size: + */ + if (copy->vertex_size * copy->limits->max_verts <= copy->limits->max_vb_size) { + copy->dstbuf_size = copy->limits->max_verts; + } + else { + copy->dstbuf_size = copy->limits->max_vb_size / copy->vertex_size; + } + + /* Allocate an output vertex buffer: + * + * XXX: This should be a VBO! + */ + copy->dstbuf = malloc(copy->dstbuf_size * copy->vertex_size); + copy->dstptr = copy->dstbuf; + + /* Setup new vertex arrays to point into the output buffer: + */ + for (offset = 0, i = 0; i < copy->nr_varying; i++) { + const struct gl_client_array *src = copy->varying[i].array; + struct gl_client_array *dst = ©->varying[i].dstarray; + + dst->Size = src->Size; + dst->Type = src->Type; + dst->Format = GL_RGBA; + dst->Stride = copy->vertex_size; + dst->StrideB = copy->vertex_size; + dst->Ptr = copy->dstbuf + offset; + dst->Enabled = GL_TRUE; + dst->Normalized = src->Normalized; + dst->BufferObj = ctx->Shared->NullBufferObj; + dst->_MaxElement = copy->dstbuf_size; /* may be less! */ + + offset += copy->varying[i].size; + } + + /* Allocate an output element list: + */ + copy->dstelt_size = MIN2(65536, + copy->ib->count * 2 + 3); + copy->dstelt_size = MIN2(copy->dstelt_size, + copy->limits->max_indices); + copy->dstelt = malloc(sizeof(GLuint) * copy->dstelt_size); + copy->dstelt_nr = 0; + + /* Setup the new index buffer to point to the allocated element + * list: + */ + copy->dstib.count = 0; /* duplicates dstelt_nr */ + copy->dstib.type = GL_UNSIGNED_INT; + copy->dstib.obj = ctx->Shared->NullBufferObj; + copy->dstib.ptr = copy->dstelt; +} + + +/** + * Free up everything allocated during split/replay. + */ +static void +replay_finish( struct copy_context *copy ) +{ + struct gl_context *ctx = copy->ctx; + GLuint i; + + /* Free our vertex and index buffers: + */ + free(copy->translated_elt_buf); + free(copy->dstbuf); + free(copy->dstelt); + + /* Unmap VBO's + */ + for (i = 0; i < copy->nr_varying; i++) { + struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj; + if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo)) + ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, vbo); + } + + /* Unmap index buffer: + */ + if (_mesa_is_bufferobj(copy->ib->obj) && + _mesa_bufferobj_mapped(copy->ib->obj)) { + ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, copy->ib->obj); + } +} + + +/** + * Split VBO into smaller pieces, draw the pieces. + */ +void vbo_split_copy( struct gl_context *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + vbo_draw_func draw, + const struct split_limits *limits ) +{ + struct copy_context copy; + GLuint i, this_nr_prims; + + for (i = 0; i < nr_prims;) { + /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices + * will rebase the elements to the basevertex, and we'll only + * emit strings of prims with the same basevertex in one draw call. + */ + for (this_nr_prims = 1; i + this_nr_prims < nr_prims; + this_nr_prims++) { + if (prim[i].basevertex != prim[i + this_nr_prims].basevertex) + break; + } + + memset(©, 0, sizeof(copy)); + + /* Require indexed primitives: + */ + assert(ib); + + copy.ctx = ctx; + copy.array = arrays; + copy.prim = &prim[i]; + copy.nr_prims = this_nr_prims; + copy.ib = ib; + copy.draw = draw; + copy.limits = limits; + + /* Clear the vertex cache: + */ + for (i = 0; i < ELT_TABLE_SIZE; i++) + copy.vert_cache[i].in = ~0; + + replay_init(©); + replay_elts(©); + replay_finish(©); + } +} diff --git a/mesalib/src/mesa/vbo/vbo_split_inplace.c b/mesalib/src/mesa/vbo/vbo_split_inplace.c index 37db87335..f6aa576b6 100644 --- a/mesalib/src/mesa/vbo/vbo_split_inplace.c +++ b/mesalib/src/mesa/vbo/vbo_split_inplace.c @@ -1,284 +1,285 @@ -
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#include "main/mtypes.h"
-#include "main/macros.h"
-#include "main/enums.h"
-#include "main/image.h"
-#include "vbo_split.h"
-
-
-#define MAX_PRIM 32
-
-/* Used for splitting without copying. No attempt is made to handle
- * too large indexed vertex buffers: In general you need to copy to do
- * that.
- */
-struct split_context {
- struct gl_context *ctx;
- const struct gl_client_array **array;
- const struct _mesa_prim *prim;
- GLuint nr_prims;
- const struct _mesa_index_buffer *ib;
- GLuint min_index;
- GLuint max_index;
- vbo_draw_func draw;
-
- const struct split_limits *limits;
- GLuint limit;
-
- struct _mesa_prim dstprim[MAX_PRIM];
- GLuint dstprim_nr;
-};
-
-
-
-
-static void flush_vertex( struct split_context *split )
-{
- struct _mesa_index_buffer ib;
- GLuint i;
-
- if (!split->dstprim_nr)
- return;
-
- if (split->ib) {
- ib = *split->ib;
-
- ib.count = split->max_index - split->min_index + 1;
- ib.ptr = (const void *)((const char *)ib.ptr +
- split->min_index * _mesa_sizeof_type(ib.type));
-
- /* Rebase the primitives to save index buffer entries. */
- for (i = 0; i < split->dstprim_nr; i++)
- split->dstprim[i].start -= split->min_index;
- }
-
- assert(split->max_index >= split->min_index);
-
- split->draw(split->ctx,
- split->array,
- split->dstprim,
- split->dstprim_nr,
- split->ib ? &ib : NULL,
- !split->ib,
- split->min_index,
- split->max_index);
-
- split->dstprim_nr = 0;
- split->min_index = ~0;
- split->max_index = 0;
-}
-
-
-static struct _mesa_prim *next_outprim( struct split_context *split )
-{
- if (split->dstprim_nr == MAX_PRIM-1) {
- flush_vertex(split);
- }
-
- {
- struct _mesa_prim *prim = &split->dstprim[split->dstprim_nr++];
- memset(prim, 0, sizeof(*prim));
- return prim;
- }
-}
-
-static void update_index_bounds(struct split_context *split,
- const struct _mesa_prim *prim)
-{
- split->min_index = MIN2(split->min_index, prim->start);
- split->max_index = MAX2(split->max_index, prim->start + prim->count - 1);
-}
-
-/* Return the maximum amount of vertices that can be emitted for a
- * primitive starting at 'prim->start', depending on the previous
- * index bounds.
- */
-static GLuint get_max_vertices(struct split_context *split,
- const struct _mesa_prim *prim)
-{
- if ((prim->start > split->min_index &&
- prim->start - split->min_index >= split->limit) ||
- (prim->start < split->max_index &&
- split->max_index - prim->start >= split->limit))
- /* "prim" starts too far away from the old range. */
- return 0;
-
- return MIN2(split->min_index, prim->start) + split->limit - prim->start;
-}
-
-/* Break large primitives into smaller ones. If not possible, convert
- * the primitive to indexed and pass to split_elts().
- */
-static void split_prims( struct split_context *split)
-{
- GLuint i;
-
- for (i = 0; i < split->nr_prims; i++) {
- const struct _mesa_prim *prim = &split->prim[i];
- GLuint first, incr;
- GLboolean split_inplace = split_prim_inplace(prim->mode, &first, &incr);
- GLuint available = get_max_vertices(split, prim);
- GLuint count = prim->count - (prim->count - first) % incr;
-
- if (prim->count < first)
- continue;
-
- if ((available < count && !split_inplace) ||
- (available < first && split_inplace)) {
- flush_vertex(split);
- available = get_max_vertices(split, prim);
- }
-
- if (available >= count) {
- struct _mesa_prim *outprim = next_outprim(split);
-
- *outprim = *prim;
- update_index_bounds(split, outprim);
- }
- else if (split_inplace) {
- GLuint j, nr;
-
- for (j = 0 ; j < count ; ) {
- GLuint remaining = count - j;
- struct _mesa_prim *outprim = next_outprim(split);
-
- nr = MIN2( available, remaining );
- nr -= (nr - first) % incr;
-
- outprim->mode = prim->mode;
- outprim->begin = (j == 0 && prim->begin);
- outprim->end = (nr == remaining && prim->end);
- outprim->start = prim->start + j;
- outprim->count = nr;
- outprim->num_instances = prim->num_instances;
-
- update_index_bounds(split, outprim);
-
- if (nr == remaining) {
- /* Finished.
- */
- j += nr;
- }
- else {
- /* Wrapped the primitive:
- */
- j += nr - (first - incr);
- flush_vertex(split);
- available = get_max_vertices(split, prim);
- }
- }
- }
- else if (split->ib == NULL) {
- /* XXX: could at least send the first max_verts off from the
- * inplace buffers.
- */
-
- /* else convert to indexed primitive and pass to split_elts,
- * which will do the necessary copying and turn it back into a
- * vertex primitive for rendering...
- */
- struct _mesa_index_buffer ib;
- struct _mesa_prim tmpprim;
- GLuint *elts = malloc(count * sizeof(GLuint));
- GLuint j;
-
- for (j = 0; j < count; j++)
- elts[j] = prim->start + j;
-
- ib.count = count;
- ib.type = GL_UNSIGNED_INT;
- ib.obj = split->ctx->Shared->NullBufferObj;
- ib.ptr = elts;
-
- tmpprim = *prim;
- tmpprim.indexed = 1;
- tmpprim.start = 0;
- tmpprim.count = count;
-
- flush_vertex(split);
-
- vbo_split_copy(split->ctx,
- split->array,
- &tmpprim, 1,
- &ib,
- split->draw,
- split->limits);
-
- free(elts);
- }
- else {
- flush_vertex(split);
-
- vbo_split_copy(split->ctx,
- split->array,
- prim, 1,
- split->ib,
- split->draw,
- split->limits);
- }
- }
-
- flush_vertex(split);
-}
-
-
-void vbo_split_inplace( struct gl_context *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_prim *prim,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLuint min_index,
- GLuint max_index,
- vbo_draw_func draw,
- const struct split_limits *limits )
-{
- struct split_context split;
-
- memset(&split, 0, sizeof(split));
-
- split.ctx = ctx;
- split.array = arrays;
- split.prim = prim;
- split.nr_prims = nr_prims;
- split.ib = ib;
-
- /* Empty interval, makes calculations simpler. */
- split.min_index = ~0;
- split.max_index = 0;
-
- split.draw = draw;
- split.limits = limits;
- split.limit = ib ? limits->max_indices : limits->max_verts;
-
- split_prims( &split );
-}
-
-
+ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/enums.h" +#include "main/image.h" +#include "vbo_split.h" + + +#define MAX_PRIM 32 + +/* Used for splitting without copying. No attempt is made to handle + * too large indexed vertex buffers: In general you need to copy to do + * that. + */ +struct split_context { + struct gl_context *ctx; + const struct gl_client_array **array; + const struct _mesa_prim *prim; + GLuint nr_prims; + const struct _mesa_index_buffer *ib; + GLuint min_index; + GLuint max_index; + vbo_draw_func draw; + + const struct split_limits *limits; + GLuint limit; + + struct _mesa_prim dstprim[MAX_PRIM]; + GLuint dstprim_nr; +}; + + + + +static void flush_vertex( struct split_context *split ) +{ + struct _mesa_index_buffer ib; + GLuint i; + + if (!split->dstprim_nr) + return; + + if (split->ib) { + ib = *split->ib; + + ib.count = split->max_index - split->min_index + 1; + ib.ptr = (const void *)((const char *)ib.ptr + + split->min_index * _mesa_sizeof_type(ib.type)); + + /* Rebase the primitives to save index buffer entries. */ + for (i = 0; i < split->dstprim_nr; i++) + split->dstprim[i].start -= split->min_index; + } + + assert(split->max_index >= split->min_index); + + split->draw(split->ctx, + split->array, + split->dstprim, + split->dstprim_nr, + split->ib ? &ib : NULL, + !split->ib, + split->min_index, + split->max_index); + + split->dstprim_nr = 0; + split->min_index = ~0; + split->max_index = 0; +} + + +static struct _mesa_prim *next_outprim( struct split_context *split ) +{ + if (split->dstprim_nr == MAX_PRIM-1) { + flush_vertex(split); + } + + { + struct _mesa_prim *prim = &split->dstprim[split->dstprim_nr++]; + memset(prim, 0, sizeof(*prim)); + return prim; + } +} + +static void update_index_bounds(struct split_context *split, + const struct _mesa_prim *prim) +{ + split->min_index = MIN2(split->min_index, prim->start); + split->max_index = MAX2(split->max_index, prim->start + prim->count - 1); +} + +/* Return the maximum amount of vertices that can be emitted for a + * primitive starting at 'prim->start', depending on the previous + * index bounds. + */ +static GLuint get_max_vertices(struct split_context *split, + const struct _mesa_prim *prim) +{ + if ((prim->start > split->min_index && + prim->start - split->min_index >= split->limit) || + (prim->start < split->max_index && + split->max_index - prim->start >= split->limit)) + /* "prim" starts too far away from the old range. */ + return 0; + + return MIN2(split->min_index, prim->start) + split->limit - prim->start; +} + +/* Break large primitives into smaller ones. If not possible, convert + * the primitive to indexed and pass to split_elts(). + */ +static void split_prims( struct split_context *split) +{ + GLuint i; + + for (i = 0; i < split->nr_prims; i++) { + const struct _mesa_prim *prim = &split->prim[i]; + GLuint first, incr; + GLboolean split_inplace = split_prim_inplace(prim->mode, &first, &incr); + GLuint available = get_max_vertices(split, prim); + GLuint count = prim->count - (prim->count - first) % incr; + + if (prim->count < first) + continue; + + if ((available < count && !split_inplace) || + (available < first && split_inplace)) { + flush_vertex(split); + available = get_max_vertices(split, prim); + } + + if (available >= count) { + struct _mesa_prim *outprim = next_outprim(split); + + *outprim = *prim; + update_index_bounds(split, outprim); + } + else if (split_inplace) { + GLuint j, nr; + + for (j = 0 ; j < count ; ) { + GLuint remaining = count - j; + struct _mesa_prim *outprim = next_outprim(split); + + nr = MIN2( available, remaining ); + nr -= (nr - first) % incr; + + outprim->mode = prim->mode; + outprim->begin = (j == 0 && prim->begin); + outprim->end = (nr == remaining && prim->end); + outprim->start = prim->start + j; + outprim->count = nr; + outprim->num_instances = prim->num_instances; + + update_index_bounds(split, outprim); + + if (nr == remaining) { + /* Finished. + */ + j += nr; + } + else { + /* Wrapped the primitive: + */ + j += nr - (first - incr); + flush_vertex(split); + available = get_max_vertices(split, prim); + } + } + } + else if (split->ib == NULL) { + /* XXX: could at least send the first max_verts off from the + * inplace buffers. + */ + + /* else convert to indexed primitive and pass to split_elts, + * which will do the necessary copying and turn it back into a + * vertex primitive for rendering... + */ + struct _mesa_index_buffer ib; + struct _mesa_prim tmpprim; + GLuint *elts = malloc(count * sizeof(GLuint)); + GLuint j; + + for (j = 0; j < count; j++) + elts[j] = prim->start + j; + + ib.count = count; + ib.type = GL_UNSIGNED_INT; + ib.obj = split->ctx->Shared->NullBufferObj; + ib.ptr = elts; + + tmpprim = *prim; + tmpprim.indexed = 1; + tmpprim.start = 0; + tmpprim.count = count; + tmpprim.num_instances = 1; + + flush_vertex(split); + + vbo_split_copy(split->ctx, + split->array, + &tmpprim, 1, + &ib, + split->draw, + split->limits); + + free(elts); + } + else { + flush_vertex(split); + + vbo_split_copy(split->ctx, + split->array, + prim, 1, + split->ib, + split->draw, + split->limits); + } + } + + flush_vertex(split); +} + + +void vbo_split_inplace( struct gl_context *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index, + vbo_draw_func draw, + const struct split_limits *limits ) +{ + struct split_context split; + + memset(&split, 0, sizeof(split)); + + split.ctx = ctx; + split.array = arrays; + split.prim = prim; + split.nr_prims = nr_prims; + split.ib = ib; + + /* Empty interval, makes calculations simpler. */ + split.min_index = ~0; + split.max_index = 0; + + split.draw = draw; + split.limits = limits; + split.limit = ib ? limits->max_indices : limits->max_verts; + + split_prims( &split ); +} + + |