diff options
author | marha <marha@users.sourceforge.net> | 2011-01-19 17:29:52 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-01-19 17:29:52 +0000 |
commit | a13b75f056f9f9efcf6ecb8610b40ddbbb2bbb69 (patch) | |
tree | 778ce0682518f7a0615ce5585410f3aaecb14421 | |
parent | 6e3cfc5bc8ca969856e4d56dec01870df709d75a (diff) | |
download | vcxsrv-a13b75f056f9f9efcf6ecb8610b40ddbbb2bbb69.tar.gz vcxsrv-a13b75f056f9f9efcf6ecb8610b40ddbbb2bbb69.tar.bz2 vcxsrv-a13b75f056f9f9efcf6ecb8610b40ddbbb2bbb69.zip |
xserver pixman mesa git update 19 jan 2011
87 files changed, 35018 insertions, 34126 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 ); +} + + diff --git a/pixman/configure.ac b/pixman/configure.ac index 6552f1270..e2f73dc06 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -54,7 +54,7 @@ AC_PREREQ([2.57]) m4_define([pixman_major], 0) m4_define([pixman_minor], 21) -m4_define([pixman_micro], 3) +m4_define([pixman_micro], 5) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) diff --git a/pixman/pixman/pixman-arm-common.h b/pixman/pixman/pixman-arm-common.h index ede63a629..372e9f9a8 100644 --- a/pixman/pixman/pixman-arm-common.h +++ b/pixman/pixman/pixman-arm-common.h @@ -1,316 +1,319 @@ -/*
- * Copyright © 2010 Nokia 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.
- *
- * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
- */
-
-#ifndef PIXMAN_ARM_COMMON_H
-#define PIXMAN_ARM_COMMON_H
-
-#include "pixman-fast-path.h"
-
-/* Define some macros which can expand into proxy functions between
- * ARM assembly optimized functions and the rest of pixman fast path API.
- *
- * All the low level ARM assembly functions have to use ARM EABI
- * calling convention and take up to 8 arguments:
- * width, height, dst, dst_stride, src, src_stride, mask, mask_stride
- *
- * The arguments are ordered with the most important coming first (the
- * first 4 arguments are passed to function in registers, the rest are
- * on stack). The last arguments are optional, for example if the
- * function is not using mask, then 'mask' and 'mask_stride' can be
- * omitted when doing a function call.
- *
- * Arguments 'src' and 'mask' contain either a pointer to the top left
- * pixel of the composited rectangle or a pixel color value depending
- * on the function type. In the case of just a color value (solid source
- * or mask), the corresponding stride argument is unused.
- */
-
-#define SKIP_ZERO_SRC 1
-#define SKIP_ZERO_MASK 2
-
-#define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name, \
- src_type, src_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- src_type *src_line; \
- int32_t dst_stride, src_stride; \
- \
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
- src_stride, src_line, src_cnt); \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_N_DST(flags, cputype, name, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- uint32_t src); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- int32_t dst_stride; \
- uint32_t src; \
- \
- src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
- \
- if ((flags & SKIP_ZERO_SRC) && src == 0) \
- return; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST(flags, cputype, name, \
- mask_type, mask_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- uint32_t src, \
- int32_t unused, \
- mask_type *mask, \
- int32_t mask_stride); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- mask_type *mask_line; \
- int32_t dst_stride, mask_stride; \
- uint32_t src; \
- \
- src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
- \
- if ((flags & SKIP_ZERO_SRC) && src == 0) \
- return; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
- mask_stride, mask_line, mask_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src, 0, \
- mask_line, mask_stride); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST(flags, cputype, name, \
- src_type, src_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride, \
- uint32_t mask); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- src_type *src_line; \
- int32_t dst_stride, src_stride; \
- uint32_t mask; \
- \
- mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);\
- \
- if ((flags & SKIP_ZERO_MASK) && mask == 0) \
- return; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
- src_stride, src_line, src_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride, \
- mask); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name, \
- src_type, src_cnt, \
- mask_type, mask_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride, \
- mask_type *mask, \
- int32_t mask_stride); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- src_type *src_line; \
- mask_type *mask_line; \
- int32_t dst_stride, src_stride, mask_stride; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
- src_stride, src_line, src_cnt); \
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
- mask_stride, mask_line, mask_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride, \
- mask_line, mask_stride); \
-}
-
-#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST(cputype, name, op, \
- src_type, dst_type) \
-void \
-pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \
- int32_t w, \
- dst_type * dst, \
- src_type * src, \
- pixman_fixed_t vx, \
- pixman_fixed_t unit_x);\
- \
-static force_inline void \
-scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \
- src_type * ps, \
- int32_t w, \
- pixman_fixed_t vx, \
- pixman_fixed_t unit_x, \
- pixman_fixed_t max_vx) \
-{ \
- pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \
- vx, unit_x);\
-} \
- \
-FAST_NEAREST_MAINLOOP (cputype##_##name##_cover_##op, \
- scaled_nearest_scanline_##cputype##_##name##_##op, \
- src_type, dst_type, COVER) \
-FAST_NEAREST_MAINLOOP (cputype##_##name##_none_##op, \
- scaled_nearest_scanline_##cputype##_##name##_##op, \
- src_type, dst_type, NONE) \
-FAST_NEAREST_MAINLOOP (cputype##_##name##_pad_##op, \
- scaled_nearest_scanline_##cputype##_##name##_##op, \
- src_type, dst_type, PAD)
-
-/* Provide entries for the fast path table */
-#define PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \
- SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \
- SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \
- SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func)
-
-#endif
+/* + * Copyright © 2010 Nokia 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. + * + * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) + */ + +#ifndef PIXMAN_ARM_COMMON_H +#define PIXMAN_ARM_COMMON_H + +#include "pixman-fast-path.h" + +/* Define some macros which can expand into proxy functions between + * ARM assembly optimized functions and the rest of pixman fast path API. + * + * All the low level ARM assembly functions have to use ARM EABI + * calling convention and take up to 8 arguments: + * width, height, dst, dst_stride, src, src_stride, mask, mask_stride + * + * The arguments are ordered with the most important coming first (the + * first 4 arguments are passed to function in registers, the rest are + * on stack). The last arguments are optional, for example if the + * function is not using mask, then 'mask' and 'mask_stride' can be + * omitted when doing a function call. + * + * Arguments 'src' and 'mask' contain either a pointer to the top left + * pixel of the composited rectangle or a pixel color value depending + * on the function type. In the case of just a color value (solid source + * or mask), the corresponding stride argument is unused. + */ + +#define SKIP_ZERO_SRC 1 +#define SKIP_ZERO_MASK 2 + +#define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name, \ + src_type, src_cnt, \ + dst_type, dst_cnt) \ +void \ +pixman_composite_##name##_asm_##cputype (int32_t w, \ + int32_t h, \ + dst_type *dst, \ + int32_t dst_stride, \ + src_type *src, \ + int32_t src_stride); \ + \ +static void \ +cputype##_composite_##name (pixman_implementation_t *imp, \ + pixman_op_t op, \ + pixman_image_t * src_image, \ + pixman_image_t * mask_image, \ + pixman_image_t * dst_image, \ + int32_t src_x, \ + int32_t src_y, \ + int32_t mask_x, \ + int32_t mask_y, \ + int32_t dest_x, \ + int32_t dest_y, \ + int32_t width, \ + int32_t height) \ +{ \ + dst_type *dst_line; \ + src_type *src_line; \ + int32_t dst_stride, src_stride; \ + \ + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ + src_stride, src_line, src_cnt); \ + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \ + dst_stride, dst_line, dst_cnt); \ + \ + pixman_composite_##name##_asm_##cputype (width, height, \ + dst_line, dst_stride, \ + src_line, src_stride); \ +} + +#define PIXMAN_ARM_BIND_FAST_PATH_N_DST(flags, cputype, name, \ + dst_type, dst_cnt) \ +void \ +pixman_composite_##name##_asm_##cputype (int32_t w, \ + int32_t h, \ + dst_type *dst, \ + int32_t dst_stride, \ + uint32_t src); \ + \ +static void \ +cputype##_composite_##name (pixman_implementation_t *imp, \ + pixman_op_t op, \ + pixman_image_t * src_image, \ + pixman_image_t * mask_image, \ + pixman_image_t * dst_image, \ + int32_t src_x, \ + int32_t src_y, \ + int32_t mask_x, \ + int32_t mask_y, \ + int32_t dest_x, \ + int32_t dest_y, \ + int32_t width, \ + int32_t height) \ +{ \ + dst_type *dst_line; \ + int32_t dst_stride; \ + uint32_t src; \ + \ + src = _pixman_image_get_solid ( \ + imp, src_image, dst_image->bits.format); \ + \ + if ((flags & SKIP_ZERO_SRC) && src == 0) \ + return; \ + \ + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \ + dst_stride, dst_line, dst_cnt); \ + \ + pixman_composite_##name##_asm_##cputype (width, height, \ + dst_line, dst_stride, \ + src); \ +} + +#define PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST(flags, cputype, name, \ + mask_type, mask_cnt, \ + dst_type, dst_cnt) \ +void \ +pixman_composite_##name##_asm_##cputype (int32_t w, \ + int32_t h, \ + dst_type *dst, \ + int32_t dst_stride, \ + uint32_t src, \ + int32_t unused, \ + mask_type *mask, \ + int32_t mask_stride); \ + \ +static void \ +cputype##_composite_##name (pixman_implementation_t *imp, \ + pixman_op_t op, \ + pixman_image_t * src_image, \ + pixman_image_t * mask_image, \ + pixman_image_t * dst_image, \ + int32_t src_x, \ + int32_t src_y, \ + int32_t mask_x, \ + int32_t mask_y, \ + int32_t dest_x, \ + int32_t dest_y, \ + int32_t width, \ + int32_t height) \ +{ \ + dst_type *dst_line; \ + mask_type *mask_line; \ + int32_t dst_stride, mask_stride; \ + uint32_t src; \ + \ + src = _pixman_image_get_solid ( \ + imp, src_image, dst_image->bits.format); \ + \ + if ((flags & SKIP_ZERO_SRC) && src == 0) \ + return; \ + \ + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \ + dst_stride, dst_line, dst_cnt); \ + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ + mask_stride, mask_line, mask_cnt); \ + \ + pixman_composite_##name##_asm_##cputype (width, height, \ + dst_line, dst_stride, \ + src, 0, \ + mask_line, mask_stride); \ +} + +#define PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST(flags, cputype, name, \ + src_type, src_cnt, \ + dst_type, dst_cnt) \ +void \ +pixman_composite_##name##_asm_##cputype (int32_t w, \ + int32_t h, \ + dst_type *dst, \ + int32_t dst_stride, \ + src_type *src, \ + int32_t src_stride, \ + uint32_t mask); \ + \ +static void \ +cputype##_composite_##name (pixman_implementation_t *imp, \ + pixman_op_t op, \ + pixman_image_t * src_image, \ + pixman_image_t * mask_image, \ + pixman_image_t * dst_image, \ + int32_t src_x, \ + int32_t src_y, \ + int32_t mask_x, \ + int32_t mask_y, \ + int32_t dest_x, \ + int32_t dest_y, \ + int32_t width, \ + int32_t height) \ +{ \ + dst_type *dst_line; \ + src_type *src_line; \ + int32_t dst_stride, src_stride; \ + uint32_t mask; \ + \ + mask = _pixman_image_get_solid ( \ + imp, mask_image, dst_image->bits.format); \ + \ + if ((flags & SKIP_ZERO_MASK) && mask == 0) \ + return; \ + \ + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \ + dst_stride, dst_line, dst_cnt); \ + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ + src_stride, src_line, src_cnt); \ + \ + pixman_composite_##name##_asm_##cputype (width, height, \ + dst_line, dst_stride, \ + src_line, src_stride, \ + mask); \ +} + +#define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name, \ + src_type, src_cnt, \ + mask_type, mask_cnt, \ + dst_type, dst_cnt) \ +void \ +pixman_composite_##name##_asm_##cputype (int32_t w, \ + int32_t h, \ + dst_type *dst, \ + int32_t dst_stride, \ + src_type *src, \ + int32_t src_stride, \ + mask_type *mask, \ + int32_t mask_stride); \ + \ +static void \ +cputype##_composite_##name (pixman_implementation_t *imp, \ + pixman_op_t op, \ + pixman_image_t * src_image, \ + pixman_image_t * mask_image, \ + pixman_image_t * dst_image, \ + int32_t src_x, \ + int32_t src_y, \ + int32_t mask_x, \ + int32_t mask_y, \ + int32_t dest_x, \ + int32_t dest_y, \ + int32_t width, \ + int32_t height) \ +{ \ + dst_type *dst_line; \ + src_type *src_line; \ + mask_type *mask_line; \ + int32_t dst_stride, src_stride, mask_stride; \ + \ + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \ + dst_stride, dst_line, dst_cnt); \ + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ + src_stride, src_line, src_cnt); \ + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ + mask_stride, mask_line, mask_cnt); \ + \ + pixman_composite_##name##_asm_##cputype (width, height, \ + dst_line, dst_stride, \ + src_line, src_stride, \ + mask_line, mask_stride); \ +} + +#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST(cputype, name, op, \ + src_type, dst_type) \ +void \ +pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \ + int32_t w, \ + dst_type * dst, \ + src_type * src, \ + pixman_fixed_t vx, \ + pixman_fixed_t unit_x);\ + \ +static force_inline void \ +scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \ + src_type * ps, \ + int32_t w, \ + pixman_fixed_t vx, \ + pixman_fixed_t unit_x, \ + pixman_fixed_t max_vx) \ +{ \ + pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \ + vx, unit_x);\ +} \ + \ +FAST_NEAREST_MAINLOOP (cputype##_##name##_cover_##op, \ + scaled_nearest_scanline_##cputype##_##name##_##op, \ + src_type, dst_type, COVER) \ +FAST_NEAREST_MAINLOOP (cputype##_##name##_none_##op, \ + scaled_nearest_scanline_##cputype##_##name##_##op, \ + src_type, dst_type, NONE) \ +FAST_NEAREST_MAINLOOP (cputype##_##name##_pad_##op, \ + scaled_nearest_scanline_##cputype##_##name##_##op, \ + src_type, dst_type, PAD) + +/* Provide entries for the fast path table */ +#define PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \ + SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \ + SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \ + SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func) + +#endif diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c index c453e0ee6..a865d719a 100644 --- a/pixman/pixman/pixman-bits-image.c +++ b/pixman/pixman/pixman-bits-image.c @@ -35,43 +35,41 @@ #include "pixman-private.h" #include "pixman-combine32.h" -/* Store functions */ -void -_pixman_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) +/* + * By default, just evaluate the image at 32bpp and expand. Individual image + * types can plug in a better scanline getter if they want to. For example + * we could produce smoother gradients by evaluating them at higher color + * depth, but that's a project for the future. + */ +static void +_pixman_image_get_scanline_generic_64 (pixman_image_t * image, + int x, + int y, + int width, + uint32_t * buffer, + const uint32_t * mask) { - image->store_scanline_32 (image, x, y, width, buffer); + uint32_t *mask8 = NULL; - if (image->common.alpha_map) + /* Contract the mask image, if one exists, so that the 32-bit fetch + * function can use it. + */ + if (mask) { - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; + mask8 = pixman_malloc_ab (width, sizeof(uint32_t)); + if (!mask8) + return; - image->common.alpha_map->store_scanline_32 ( - image->common.alpha_map, x, y, width, buffer); + pixman_contract (mask8, (uint64_t *)mask, width); } -} -void -_pixman_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ - image->store_scanline_64 (image, x, y, width, buffer); + /* Fetch the source image into the first half of buffer. */ + image->bits.get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8); - if (image->common.alpha_map) - { - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; + /* Expand from 32bpp to 64bpp in place. */ + pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width); - image->common.alpha_map->store_scanline_64 ( - image->common.alpha_map, x, y, width, buffer); - } + free (mask8); } /* Fetch functions */ @@ -297,6 +295,7 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima, uint32_t *bottom_row; uint32_t *end; uint32_t zero[2] = { 0, 0 }; + uint32_t one = 1; int y, y1, y2; int disty; int mask_inc; @@ -362,10 +361,8 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima, */ if (!mask) { - uint32_t mask_bits = 1; - mask_inc = 0; - mask = &mask_bits; + mask = &one; } else { @@ -1337,8 +1334,8 @@ bits_image_property_changed (pixman_image_t *image) if ((info->format == format || info->format == PIXMAN_any) && (info->flags & flags) == info->flags) { - image->common.get_scanline_32 = info->fetch_32; - image->common.get_scanline_64 = info->fetch_64; + image->bits.get_scanline_32 = info->fetch_32; + image->bits.get_scanline_64 = info->fetch_64; break; } @@ -1347,6 +1344,176 @@ bits_image_property_changed (pixman_image_t *image) } static uint32_t * +src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + iter->image->bits.get_scanline_32 ( + iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask); + + return iter->buffer; +} + +static uint32_t * +src_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + iter->image->bits.get_scanline_64 ( + iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask); + + return iter->buffer; +} + +void +_pixman_bits_image_src_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + iter->get_scanline = src_get_scanline_narrow; + else + iter->get_scanline = src_get_scanline_wide; +} + +static uint32_t * +dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + pixman_image_t *image = iter->image; + int x = iter->x; + int y = iter->y; + int width = iter->width; + uint32_t * buffer = iter->buffer; + + image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask); + if (image->common.alpha_map) + { + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; + + image->common.alpha_map->fetch_scanline_32 ( + (pixman_image_t *)image->common.alpha_map, + x, y, width, buffer, mask); + } + + return iter->buffer; +} + +static uint32_t * +dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + bits_image_t * image = &iter->image->bits; + int x = iter->x; + int y = iter->y; + int width = iter->width; + uint32_t * buffer = iter->buffer; + + image->fetch_scanline_64 ( + (pixman_image_t *)image, x, y, width, buffer, mask); + if (image->common.alpha_map) + { + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; + + image->common.alpha_map->fetch_scanline_64 ( + (pixman_image_t *)image->common.alpha_map, x, y, width, buffer, mask); + } + + return iter->buffer; +} + +static void +dest_write_back_narrow (pixman_iter_t *iter) +{ + bits_image_t * image = &iter->image->bits; + int x = iter->x; + int y = iter->y; + int width = iter->width; + const uint32_t *buffer = iter->buffer; + + image->store_scanline_32 (image, x, y, width, buffer); + + if (image->common.alpha_map) + { + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; + + image->common.alpha_map->store_scanline_32 ( + image->common.alpha_map, x, y, width, buffer); + } + + iter->y++; +} + +static void +dest_write_back_wide (pixman_iter_t *iter) +{ + bits_image_t * image = &iter->image->bits; + int x = iter->x; + int y = iter->y; + int width = iter->width; + const uint32_t *buffer = iter->buffer; + + image->store_scanline_64 (image, x, y, width, buffer); + + if (image->common.alpha_map) + { + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; + + image->common.alpha_map->store_scanline_64 ( + image->common.alpha_map, x, y, width, buffer); + } + + iter->y++; +} + +static void +dest_write_back_direct (pixman_iter_t *iter) +{ + iter->buffer += iter->image->bits.rowstride; +} + +void +_pixman_bits_image_dest_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + { + if (((image->common.flags & + (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) == + (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) && + (image->bits.format == PIXMAN_a8r8g8b8 || + (image->bits.format == PIXMAN_x8r8g8b8 && + (flags & ITER_LOCALIZED_ALPHA)))) + { + iter->buffer = image->bits.bits + y * image->bits.rowstride + x; + + iter->get_scanline = _pixman_iter_get_scanline_noop; + iter->write_back = dest_write_back_direct; + } + else + { + if ((flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == + (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) + { + iter->get_scanline = _pixman_iter_get_scanline_noop; + } + else + { + iter->get_scanline = dest_get_scanline_narrow; + } + + iter->write_back = dest_write_back_narrow; + } + } + else + { + iter->get_scanline = dest_get_scanline_wide; + iter->write_back = dest_write_back_wide; + } +} + +static uint32_t * create_bits (pixman_format_code_t format, int width, int height, diff --git a/pixman/pixman/pixman-conical-gradient.c b/pixman/pixman/pixman-conical-gradient.c index 769b984d1..9d7d2e8b5 100644 --- a/pixman/pixman/pixman-conical-gradient.c +++ b/pixman/pixman/pixman-conical-gradient.c @@ -1,197 +1,214 @@ -/*
- * Copyright © 2000 SuSE, Inc.
- * Copyright © 2007 Red Hat, Inc.
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- * 2005 Lars Knoll & Zack Rusin, Trolltech
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <math.h>
-#include "pixman-private.h"
-
-static force_inline double
-coordinates_to_parameter (double x, double y, double angle)
-{
- double t;
-
- t = atan2 (y, x) + angle;
-
- while (t < 0)
- t += 2 * M_PI;
-
- while (t >= 2 * M_PI)
- t -= 2 * M_PI;
-
- return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and
- * make rotation CCW
- */
-}
-
-static void
-conical_gradient_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- gradient_t *gradient = (gradient_t *)image;
- conical_gradient_t *conical = (conical_gradient_t *)image;
- uint32_t *end = buffer + width;
- pixman_gradient_walker_t walker;
- pixman_bool_t affine = TRUE;
- double cx = 1.;
- double cy = 0.;
- double cz = 0.;
- double rx = x + 0.5;
- double ry = y + 0.5;
- double rz = 1.;
-
- _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
-
- if (image->common.transform)
- {
- pixman_vector_t v;
-
- /* reference point is the center of the pixel */
- v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
- v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
- v.vector[2] = pixman_fixed_1;
-
- if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
-
- cx = image->common.transform->matrix[0][0] / 65536.;
- cy = image->common.transform->matrix[1][0] / 65536.;
- cz = image->common.transform->matrix[2][0] / 65536.;
-
- rx = v.vector[0] / 65536.;
- ry = v.vector[1] / 65536.;
- rz = v.vector[2] / 65536.;
-
- affine =
- image->common.transform->matrix[2][0] == 0 &&
- v.vector[2] == pixman_fixed_1;
- }
-
- if (affine)
- {
- rx -= conical->center.x / 65536.;
- ry -= conical->center.y / 65536.;
-
- while (buffer < end)
- {
- if (!mask || *mask++)
- {
- double t = coordinates_to_parameter (rx, ry, conical->angle);
-
- *buffer = _pixman_gradient_walker_pixel (
- &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
- }
-
- ++buffer;
-
- rx += cx;
- ry += cy;
- }
- }
- else
- {
- while (buffer < end)
- {
- double x, y;
-
- if (!mask || *mask++)
- {
- double t;
-
- if (rz != 0)
- {
- x = rx / rz;
- y = ry / rz;
- }
- else
- {
- x = y = 0.;
- }
-
- x -= conical->center.x / 65536.;
- y -= conical->center.y / 65536.;
-
- t = coordinates_to_parameter (x, y, conical->angle);
-
- *buffer = _pixman_gradient_walker_pixel (
- &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
- }
-
- ++buffer;
-
- rx += cx;
- ry += cy;
- rz += cz;
- }
- }
-}
-
-static void
-conical_gradient_property_changed (pixman_image_t *image)
-{
- image->common.get_scanline_32 = conical_gradient_get_scanline_32;
- image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-}
-
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_conical_gradient (pixman_point_fixed_t * center,
- pixman_fixed_t angle,
- const pixman_gradient_stop_t *stops,
- int n_stops)
-{
- pixman_image_t *image = _pixman_image_allocate ();
- conical_gradient_t *conical;
-
- if (!image)
- return NULL;
-
- conical = &image->conical;
-
- if (!_pixman_init_gradient (&conical->common, stops, n_stops))
- {
- free (image);
- return NULL;
- }
-
- angle = MOD (angle, pixman_int_to_fixed (360));
-
- image->type = CONICAL;
-
- conical->center = *center;
- conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;
-
- image->common.property_changed = conical_gradient_property_changed;
-
- return image;
-}
-
+/* + * Copyright © 2000 SuSE, Inc. + * Copyright © 2007 Red Hat, Inc. + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. + * 2005 Lars Knoll & Zack Rusin, Trolltech + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <math.h> +#include "pixman-private.h" + +static force_inline double +coordinates_to_parameter (double x, double y, double angle) +{ + double t; + + t = atan2 (y, x) + angle; + + while (t < 0) + t += 2 * M_PI; + + while (t >= 2 * M_PI) + t -= 2 * M_PI; + + return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and + * make rotation CCW + */ +} + +static uint32_t * +conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + pixman_image_t *image = iter->image; + int x = iter->x; + int y = iter->y; + int width = iter->width; + uint32_t *buffer = iter->buffer; + + gradient_t *gradient = (gradient_t *)image; + conical_gradient_t *conical = (conical_gradient_t *)image; + uint32_t *end = buffer + width; + pixman_gradient_walker_t walker; + pixman_bool_t affine = TRUE; + double cx = 1.; + double cy = 0.; + double cz = 0.; + double rx = x + 0.5; + double ry = y + 0.5; + double rz = 1.; + + _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); + + if (image->common.transform) + { + pixman_vector_t v; + + /* reference point is the center of the pixel */ + v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; + v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; + v.vector[2] = pixman_fixed_1; + + if (!pixman_transform_point_3d (image->common.transform, &v)) + return iter->buffer; + + cx = image->common.transform->matrix[0][0] / 65536.; + cy = image->common.transform->matrix[1][0] / 65536.; + cz = image->common.transform->matrix[2][0] / 65536.; + + rx = v.vector[0] / 65536.; + ry = v.vector[1] / 65536.; + rz = v.vector[2] / 65536.; + + affine = + image->common.transform->matrix[2][0] == 0 && + v.vector[2] == pixman_fixed_1; + } + + if (affine) + { + rx -= conical->center.x / 65536.; + ry -= conical->center.y / 65536.; + + while (buffer < end) + { + if (!mask || *mask++) + { + double t = coordinates_to_parameter (rx, ry, conical->angle); + + *buffer = _pixman_gradient_walker_pixel ( + &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); + } + + ++buffer; + + rx += cx; + ry += cy; + } + } + else + { + while (buffer < end) + { + double x, y; + + if (!mask || *mask++) + { + double t; + + if (rz != 0) + { + x = rx / rz; + y = ry / rz; + } + else + { + x = y = 0.; + } + + x -= conical->center.x / 65536.; + y -= conical->center.y / 65536.; + + t = coordinates_to_parameter (x, y, conical->angle); + + *buffer = _pixman_gradient_walker_pixel ( + &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); + } + + ++buffer; + + rx += cx; + ry += cy; + rz += cz; + } + } + + iter->y++; + return iter->buffer; +} + +static uint32_t * +conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + uint32_t *buffer = conical_get_scanline_narrow (iter, NULL); + + pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + + return buffer; +} + +void +_pixman_conical_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + iter->get_scanline = conical_get_scanline_narrow; + else + iter->get_scanline = conical_get_scanline_wide; +} + +PIXMAN_EXPORT pixman_image_t * +pixman_image_create_conical_gradient (pixman_point_fixed_t * center, + pixman_fixed_t angle, + const pixman_gradient_stop_t *stops, + int n_stops) +{ + pixman_image_t *image = _pixman_image_allocate (); + conical_gradient_t *conical; + + if (!image) + return NULL; + + conical = &image->conical; + + if (!_pixman_init_gradient (&conical->common, stops, n_stops)) + { + free (image); + return NULL; + } + + angle = MOD (angle, pixman_int_to_fixed (360)); + + image->type = CONICAL; + + conical->center = *center; + conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI; + + return image; +} + diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c index f103b4cf1..868175f60 100644 --- a/pixman/pixman/pixman-fast-path.c +++ b/pixman/pixman/pixman-fast-path.c @@ -188,7 +188,7 @@ fast_composite_in_n_8_8 (pixman_implementation_t *imp, int32_t w; uint16_t t; - src = _pixman_image_get_solid (src_image, dest_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); srca = src >> 24; @@ -312,7 +312,7 @@ fast_composite_over_n_8_8888 (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -370,7 +370,7 @@ fast_composite_add_n_8888_8888_ca (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -427,7 +427,7 @@ fast_composite_over_n_8888_8888_ca (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -494,7 +494,7 @@ fast_composite_over_n_8_0888 (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -559,7 +559,7 @@ fast_composite_over_n_8_0565 (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -626,7 +626,7 @@ fast_composite_over_n_8888_0565_ca (pixman_implementation_t *imp, int dst_stride, mask_stride; int32_t w; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -1034,7 +1034,7 @@ fast_composite_add_n_8_8 (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); sa = (src >> 24); while (height--) @@ -1146,7 +1146,7 @@ fast_composite_over_n_1_8888 (pixman_implementation_t *imp, if (width <= 0) return; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) return; @@ -1240,7 +1240,7 @@ fast_composite_over_n_1_0565 (pixman_implementation_t *imp, if (width <= 0) return; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) return; @@ -1332,7 +1332,7 @@ fast_composite_solid_fill (pixman_implementation_t *imp, { uint32_t src; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); if (dst_image->bits.format == PIXMAN_a1) { diff --git a/pixman/pixman/pixman-general.c b/pixman/pixman/pixman-general.c index 5a639051b..16ea3a457 100644 --- a/pixman/pixman/pixman-general.c +++ b/pixman/pixman/pixman-general.c @@ -1,315 +1,313 @@ -/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2000 SuSE, Inc.
- * Copyright © 2007 Red Hat, Inc.
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- * 2005 Lars Knoll & Zack Rusin, Trolltech
- * 2008 Aaron Plattner, NVIDIA Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Red Hat not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Red Hat makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "pixman-private.h"
-#include "pixman-combine32.h"
-#include "pixman-private.h"
-
-#define SCANLINE_BUFFER_LENGTH 8192
-
-static void
-general_composite_rect (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
- uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
- uint8_t *src_buffer, *mask_buffer, *dest_buffer;
- fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL;
- pixman_combine_32_func_t compose;
- store_scanline_t store;
- source_image_class_t src_class, mask_class;
- pixman_bool_t component_alpha;
- uint32_t *bits;
- int32_t stride;
- int narrow, Bpp;
- int i;
-
- narrow =
- (src->common.flags & FAST_PATH_NARROW_FORMAT) &&
- (!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
- (dest->common.flags & FAST_PATH_NARROW_FORMAT);
- Bpp = narrow ? 4 : 8;
-
- if (width * Bpp > SCANLINE_BUFFER_LENGTH)
- {
- scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
-
- if (!scanline_buffer)
- return;
- }
-
- src_buffer = scanline_buffer;
- mask_buffer = src_buffer + width * Bpp;
- dest_buffer = mask_buffer + width * Bpp;
-
- src_class = _pixman_image_classify (src,
- src_x, src_y,
- width, height);
-
- mask_class = SOURCE_IMAGE_CLASS_UNKNOWN;
-
- if (mask)
- {
- mask_class = _pixman_image_classify (mask,
- src_x, src_y,
- width, height);
- }
-
- if (op == PIXMAN_OP_CLEAR)
- fetch_src = NULL;
- else if (narrow)
- fetch_src = _pixman_image_get_scanline_32;
- else
- fetch_src = _pixman_image_get_scanline_64;
-
- if (!mask || op == PIXMAN_OP_CLEAR)
- fetch_mask = NULL;
- else if (narrow)
- fetch_mask = _pixman_image_get_scanline_32;
- else
- fetch_mask = _pixman_image_get_scanline_64;
-
- if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC)
- fetch_dest = NULL;
- else if (narrow)
- fetch_dest = _pixman_image_get_scanline_32;
- else
- fetch_dest = _pixman_image_get_scanline_64;
-
- if (narrow)
- store = _pixman_image_store_scanline_32;
- else
- store = _pixman_image_store_scanline_64;
-
- /* Skip the store step and composite directly into the
- * destination if the output format of the compose func matches
- * the destination format.
- *
- * If the destination format is a8r8g8b8 then we can always do
- * this. If it is x8r8g8b8, then we can only do it if the
- * operator doesn't make use of destination alpha.
- */
- if ((dest->bits.format == PIXMAN_a8r8g8b8) ||
- (dest->bits.format == PIXMAN_x8r8g8b8 &&
- (op == PIXMAN_OP_OVER ||
- op == PIXMAN_OP_ADD ||
- op == PIXMAN_OP_SRC ||
- op == PIXMAN_OP_CLEAR ||
- op == PIXMAN_OP_IN_REVERSE ||
- op == PIXMAN_OP_OUT_REVERSE ||
- op == PIXMAN_OP_DST)))
- {
- if (narrow &&
- !dest->common.alpha_map &&
- !dest->bits.write_func)
- {
- store = NULL;
- }
- }
-
- if (!store)
- {
- bits = dest->bits.bits;
- stride = dest->bits.rowstride;
- }
- else
- {
- bits = NULL;
- stride = 0;
- }
-
- component_alpha =
- fetch_src &&
- fetch_mask &&
- mask &&
- mask->common.type == BITS &&
- mask->common.component_alpha &&
- PIXMAN_FORMAT_RGB (mask->bits.format);
-
- if (narrow)
- {
- if (component_alpha)
- compose = _pixman_implementation_combine_32_ca;
- else
- compose = _pixman_implementation_combine_32;
- }
- else
- {
- if (component_alpha)
- compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
- else
- compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64;
- }
-
- if (!compose)
- return;
-
- if (!fetch_mask)
- mask_buffer = NULL;
-
- for (i = 0; i < height; ++i)
- {
- /* fill first half of scanline with source */
- if (fetch_src)
- {
- if (fetch_mask)
- {
- /* fetch mask before source so that fetching of
- source can be optimized */
- fetch_mask (mask, mask_x, mask_y + i,
- width, (void *)mask_buffer, 0);
-
- if (mask_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
- fetch_mask = NULL;
- }
-
- if (src_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
- {
- fetch_src (src, src_x, src_y + i,
- width, (void *)src_buffer, 0);
- fetch_src = NULL;
- }
- else
- {
- fetch_src (src, src_x, src_y + i,
- width, (void *)src_buffer, (void *)mask_buffer);
- }
- }
- else if (fetch_mask)
- {
- fetch_mask (mask, mask_x, mask_y + i,
- width, (void *)mask_buffer, 0);
- }
-
- if (store)
- {
- /* fill dest into second half of scanline */
- if (fetch_dest)
- {
- fetch_dest (dest, dest_x, dest_y + i,
- width, (void *)dest_buffer, 0);
- }
-
- /* blend */
- compose (imp->toplevel, op,
- (void *)dest_buffer,
- (void *)src_buffer,
- (void *)mask_buffer,
- width);
-
- /* write back */
- store (&(dest->bits), dest_x, dest_y + i, width,
- (void *)dest_buffer);
- }
- else
- {
- /* blend */
- compose (imp->toplevel, op,
- bits + (dest_y + i) * stride + dest_x,
- (void *)src_buffer, (void *)mask_buffer, width);
- }
- }
-
- if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
- free (scanline_buffer);
-}
-
-static const pixman_fast_path_t general_fast_path[] =
-{
- { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
- { PIXMAN_OP_NONE }
-};
-
-static pixman_bool_t
-general_blt (pixman_implementation_t *imp,
- uint32_t * src_bits,
- uint32_t * dst_bits,
- int src_stride,
- int dst_stride,
- int src_bpp,
- int dst_bpp,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height)
-{
- /* We can't blit unless we have sse2 or mmx */
-
- return FALSE;
-}
-
-static pixman_bool_t
-general_fill (pixman_implementation_t *imp,
- uint32_t * bits,
- int stride,
- int bpp,
- int x,
- int y,
- int width,
- int height,
- uint32_t xor)
-{
- return FALSE;
-}
-
-pixman_implementation_t *
-_pixman_implementation_create_general (void)
-{
- pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
-
- _pixman_setup_combiner_functions_32 (imp);
- _pixman_setup_combiner_functions_64 (imp);
-
- imp->blt = general_blt;
- imp->fill = general_fill;
-
- return imp;
-}
-
+/* + * Copyright © 2009 Red Hat, Inc. + * Copyright © 2000 SuSE, Inc. + * Copyright © 2007 Red Hat, Inc. + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. + * 2005 Lars Knoll & Zack Rusin, Trolltech + * 2008 Aaron Plattner, NVIDIA Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "pixman-private.h" +#include "pixman-combine32.h" +#include "pixman-private.h" + +static void +general_src_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + iter->image = image; + iter->x = x; + iter->y = y; + iter->width = width; + iter->buffer = (uint32_t *)buffer; + + if (image->type == SOLID) + { + _pixman_solid_fill_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else if (image->type == LINEAR) + { + _pixman_linear_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else if (image->type == RADIAL) + { + _pixman_radial_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else if (image->type == CONICAL) + { + _pixman_conical_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else if (image->type == BITS) + { + _pixman_bits_image_src_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else + { + _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); + } +} + +static void +general_dest_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + iter->image = image; + iter->x = x; + iter->y = y; + iter->width = width; + iter->buffer = (uint32_t *)buffer; + + if (image->type == BITS) + { + _pixman_bits_image_dest_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else + { + _pixman_log_error (FUNC, "Trying to write to a non-writable image"); + } +} + +typedef struct op_info_t op_info_t; +struct op_info_t +{ + uint8_t src, dst; +}; + +#define ITER_IGNORE_BOTH \ + (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA) + +static const op_info_t op_flags[PIXMAN_N_OPERATORS] = +{ + /* Src Dst */ + { ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */ + { ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */ + { ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */ + { 0, ITER_LOCALIZED_ALPHA }, /* OVER */ + { ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */ + { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */ + { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */ + { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */ + { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */ + { 0, 0 }, /* ATOP */ + { 0, 0 }, /* ATOP_REVERSE */ + { 0, 0 }, /* XOR */ + { ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */ + { 0, 0 }, /* SATURATE */ +}; + +#define SCANLINE_BUFFER_LENGTH 8192 + +static void +general_composite_rect (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src, + pixman_image_t * mask, + pixman_image_t * dest, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8]; + uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer; + uint8_t *src_buffer, *mask_buffer, *dest_buffer; + pixman_iter_t src_iter, mask_iter, dest_iter; + pixman_combine_32_func_t compose; + pixman_bool_t component_alpha; + iter_flags_t narrow, src_flags; + int Bpp; + int i; + + if ((src->common.flags & FAST_PATH_NARROW_FORMAT) && + (!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) && + (dest->common.flags & FAST_PATH_NARROW_FORMAT)) + { + narrow = ITER_NARROW; + Bpp = 4; + } + else + { + narrow = 0; + Bpp = 8; + } + + if (width * Bpp > SCANLINE_BUFFER_LENGTH) + { + scanline_buffer = pixman_malloc_abc (width, 3, Bpp); + + if (!scanline_buffer) + return; + } + + src_buffer = scanline_buffer; + mask_buffer = src_buffer + width * Bpp; + dest_buffer = mask_buffer + width * Bpp; + + /* src iter */ + src_flags = narrow | op_flags[op].src; + + _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src, + src_x, src_y, width, height, + src_buffer, src_flags); + + /* mask iter */ + if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == + (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) + { + /* If it doesn't matter what the source is, then it doesn't matter + * what the mask is + */ + mask = NULL; + } + + component_alpha = + mask && + mask->common.type == BITS && + mask->common.component_alpha && + PIXMAN_FORMAT_RGB (mask->bits.format); + + _pixman_implementation_src_iter_init ( + imp->toplevel, &mask_iter, mask, mask_x, mask_y, width, height, + mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB)); + + /* dest iter */ + _pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest, + dest_x, dest_y, width, height, + dest_buffer, + narrow | op_flags[op].dst); + + if (narrow) + { + if (component_alpha) + compose = _pixman_implementation_combine_32_ca; + else + compose = _pixman_implementation_combine_32; + } + else + { + if (component_alpha) + compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca; + else + compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64; + } + + if (!compose) + return; + + for (i = 0; i < height; ++i) + { + uint32_t *s, *m, *d; + + m = mask_iter.get_scanline (&mask_iter, NULL); + s = src_iter.get_scanline (&src_iter, m); + d = dest_iter.get_scanline (&dest_iter, NULL); + + compose (imp->toplevel, op, d, s, m, width); + + dest_iter.write_back (&dest_iter); + } + + if (scanline_buffer != (uint8_t *) stack_scanline_buffer) + free (scanline_buffer); +} + +static const pixman_fast_path_t general_fast_path[] = +{ + { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect }, + { PIXMAN_OP_NONE } +}; + +static pixman_bool_t +general_blt (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height) +{ + /* We can't blit unless we have sse2 or mmx */ + + return FALSE; +} + +static pixman_bool_t +general_fill (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) +{ + return FALSE; +} + +pixman_implementation_t * +_pixman_implementation_create_general (void) +{ + pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); + + _pixman_setup_combiner_functions_32 (imp); + _pixman_setup_combiner_functions_64 (imp); + + imp->blt = general_blt; + imp->fill = general_fill; + imp->src_iter_init = general_src_iter_init; + imp->dest_iter_init = general_dest_iter_init; + + return imp; +} + diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c index 48faa3a10..a72299b3c 100644 --- a/pixman/pixman/pixman-image.c +++ b/pixman/pixman/pixman-image.c @@ -1,815 +1,747 @@ -/*
- * Copyright © 2000 SuSE, Inc.
- * Copyright © 2007 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include "pixman-private.h"
-#include "pixman-combine32.h"
-
-pixman_bool_t
-_pixman_init_gradient (gradient_t * gradient,
- const pixman_gradient_stop_t *stops,
- int n_stops)
-{
- return_val_if_fail (n_stops > 0, FALSE);
-
- gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
- if (!gradient->stops)
- return FALSE;
-
- memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
-
- gradient->n_stops = n_stops;
-
- return TRUE;
-}
-
-/*
- * By default, just evaluate the image at 32bpp and expand. Individual image
- * types can plug in a better scanline getter if they want to. For example
- * we could produce smoother gradients by evaluating them at higher color
- * depth, but that's a project for the future.
- */
-void
-_pixman_image_get_scanline_generic_64 (pixman_image_t * image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t * mask)
-{
- uint32_t *mask8 = NULL;
-
- /* Contract the mask image, if one exists, so that the 32-bit fetch
- * function can use it.
- */
- if (mask)
- {
- mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
- if (!mask8)
- return;
-
- pixman_contract (mask8, (uint64_t *)mask, width);
- }
-
- /* Fetch the source image into the first half of buffer. */
- _pixman_image_get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
-
- /* Expand from 32bpp to 64bpp in place. */
- pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
-
- free (mask8);
-}
-
-pixman_image_t *
-_pixman_image_allocate (void)
-{
- pixman_image_t *image = malloc (sizeof (pixman_image_t));
-
- if (image)
- {
- image_common_t *common = &image->common;
-
- pixman_region32_init (&common->clip_region);
-
- common->alpha_count = 0;
- common->have_clip_region = FALSE;
- common->clip_sources = FALSE;
- common->transform = NULL;
- common->repeat = PIXMAN_REPEAT_NONE;
- common->filter = PIXMAN_FILTER_NEAREST;
- common->filter_params = NULL;
- common->n_filter_params = 0;
- common->alpha_map = NULL;
- common->component_alpha = FALSE;
- common->ref_count = 1;
- common->classify = NULL;
- common->client_clip = FALSE;
- common->destroy_func = NULL;
- common->destroy_data = NULL;
- common->dirty = TRUE;
- }
-
- return image;
-}
-
-source_image_class_t
-_pixman_image_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height)
-{
- if (image->common.classify)
- return image->common.classify (image, x, y, width, height);
- else
- return SOURCE_IMAGE_CLASS_UNKNOWN;
-}
-
-void
-_pixman_image_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- image->common.get_scanline_32 (image, x, y, width, buffer, mask);
-}
-
-/* Even thought the type of buffer is uint32_t *, the function actually expects
- * a uint64_t *buffer.
- */
-void
-_pixman_image_get_scanline_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *unused)
-{
- image->common.get_scanline_64 (image, x, y, width, buffer, unused);
-}
-
-static void
-image_property_changed (pixman_image_t *image)
-{
- image->common.dirty = TRUE;
-}
-
-/* Ref Counting */
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_ref (pixman_image_t *image)
-{
- image->common.ref_count++;
-
- return image;
-}
-
-/* returns TRUE when the image is freed */
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_unref (pixman_image_t *image)
-{
- image_common_t *common = (image_common_t *)image;
-
- common->ref_count--;
-
- if (common->ref_count == 0)
- {
- if (image->common.destroy_func)
- image->common.destroy_func (image, image->common.destroy_data);
-
- pixman_region32_fini (&common->clip_region);
-
- if (common->transform)
- free (common->transform);
-
- if (common->filter_params)
- free (common->filter_params);
-
- if (common->alpha_map)
- pixman_image_unref ((pixman_image_t *)common->alpha_map);
-
- if (image->type == LINEAR ||
- image->type == RADIAL ||
- image->type == CONICAL)
- {
- if (image->gradient.stops)
- free (image->gradient.stops);
- }
-
- if (image->type == BITS && image->bits.free_me)
- free (image->bits.free_me);
-
- free (image);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-PIXMAN_EXPORT void
-pixman_image_set_destroy_function (pixman_image_t * image,
- pixman_image_destroy_func_t func,
- void * data)
-{
- image->common.destroy_func = func;
- image->common.destroy_data = data;
-}
-
-PIXMAN_EXPORT void *
-pixman_image_get_destroy_data (pixman_image_t *image)
-{
- return image->common.destroy_data;
-}
-
-void
-_pixman_image_reset_clip_region (pixman_image_t *image)
-{
- image->common.have_clip_region = FALSE;
-}
-
-/* Executive Summary: This function is a no-op that only exists
- * for historical reasons.
- *
- * There used to be a bug in the X server where it would rely on
- * out-of-bounds accesses when it was asked to composite with a
- * window as the source. It would create a pixman image pointing
- * to some bogus position in memory, but then set a clip region
- * to the position where the actual bits were.
- *
- * Due to a bug in old versions of pixman, where it would not clip
- * against the image bounds when a clip region was set, this would
- * actually work. So when the pixman bug was fixed, a workaround was
- * added to allow certain out-of-bound accesses. This function disabled
- * those workarounds.
- *
- * Since 0.21.2, pixman doesn't do these workarounds anymore, so now
- * this function is a no-op.
- */
-PIXMAN_EXPORT void
-pixman_disable_out_of_bounds_workaround (void)
-{
-}
-
-static void
-compute_image_info (pixman_image_t *image)
-{
- pixman_format_code_t code;
- uint32_t flags = 0;
-
- /* Transform */
- if (!image->common.transform)
- {
- flags |= (FAST_PATH_ID_TRANSFORM |
- FAST_PATH_X_UNIT_POSITIVE |
- FAST_PATH_Y_UNIT_ZERO |
- FAST_PATH_AFFINE_TRANSFORM);
- }
- else
- {
- flags |= FAST_PATH_HAS_TRANSFORM;
-
- if (image->common.transform->matrix[2][0] == 0 &&
- image->common.transform->matrix[2][1] == 0 &&
- image->common.transform->matrix[2][2] == pixman_fixed_1)
- {
- flags |= FAST_PATH_AFFINE_TRANSFORM;
-
- if (image->common.transform->matrix[0][1] == 0 &&
- image->common.transform->matrix[1][0] == 0)
- {
- flags |= FAST_PATH_SCALE_TRANSFORM;
- }
- }
-
- if (image->common.transform->matrix[0][0] > 0)
- flags |= FAST_PATH_X_UNIT_POSITIVE;
-
- if (image->common.transform->matrix[1][0] == 0)
- flags |= FAST_PATH_Y_UNIT_ZERO;
- }
-
- /* Filter */
- switch (image->common.filter)
- {
- case PIXMAN_FILTER_NEAREST:
- case PIXMAN_FILTER_FAST:
- flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
- break;
-
- case PIXMAN_FILTER_BILINEAR:
- case PIXMAN_FILTER_GOOD:
- case PIXMAN_FILTER_BEST:
- flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
- break;
-
- case PIXMAN_FILTER_CONVOLUTION:
- break;
-
- default:
- flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
- break;
- }
-
- /* Repeat mode */
- switch (image->common.repeat)
- {
- case PIXMAN_REPEAT_NONE:
- flags |=
- FAST_PATH_NO_REFLECT_REPEAT |
- FAST_PATH_NO_PAD_REPEAT |
- FAST_PATH_NO_NORMAL_REPEAT;
- break;
-
- case PIXMAN_REPEAT_REFLECT:
- flags |=
- FAST_PATH_NO_PAD_REPEAT |
- FAST_PATH_NO_NONE_REPEAT |
- FAST_PATH_NO_NORMAL_REPEAT;
- break;
-
- case PIXMAN_REPEAT_PAD:
- flags |=
- FAST_PATH_NO_REFLECT_REPEAT |
- FAST_PATH_NO_NONE_REPEAT |
- FAST_PATH_NO_NORMAL_REPEAT;
- break;
-
- default:
- flags |=
- FAST_PATH_NO_REFLECT_REPEAT |
- FAST_PATH_NO_PAD_REPEAT |
- FAST_PATH_NO_NONE_REPEAT;
- break;
- }
-
- /* Component alpha */
- if (image->common.component_alpha)
- flags |= FAST_PATH_COMPONENT_ALPHA;
- else
- flags |= FAST_PATH_UNIFIED_ALPHA;
-
- flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
-
- /* Type specific checks */
- switch (image->type)
- {
- case SOLID:
- code = PIXMAN_solid;
-
- if (image->solid.color.alpha == 0xffff)
- flags |= FAST_PATH_IS_OPAQUE;
- break;
-
- case BITS:
- if (image->bits.width == 1 &&
- image->bits.height == 1 &&
- image->common.repeat != PIXMAN_REPEAT_NONE)
- {
- code = PIXMAN_solid;
- }
- else
- {
- code = image->bits.format;
- }
-
- if (!PIXMAN_FORMAT_A (image->bits.format) &&
- PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY &&
- PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
- {
- flags |= FAST_PATH_SAMPLES_OPAQUE;
-
- if (image->common.repeat != PIXMAN_REPEAT_NONE)
- flags |= FAST_PATH_IS_OPAQUE;
- }
-
- if (image->bits.read_func || image->bits.write_func)
- flags &= ~FAST_PATH_NO_ACCESSORS;
-
- if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
- flags &= ~FAST_PATH_NARROW_FORMAT;
- break;
-
- case RADIAL:
- code = PIXMAN_unknown;
-
- /*
- * As explained in pixman-radial-gradient.c, every point of
- * the plane has a valid associated radius (and thus will be
- * colored) if and only if a is negative (i.e. one of the two
- * circles contains the other one).
- */
-
- if (image->radial.a >= 0)
- break;
-
- /* Fall through */
-
- case CONICAL:
- case LINEAR:
- code = PIXMAN_unknown;
-
- if (image->common.repeat != PIXMAN_REPEAT_NONE)
- {
- int i;
-
- flags |= FAST_PATH_IS_OPAQUE;
- for (i = 0; i < image->gradient.n_stops; ++i)
- {
- if (image->gradient.stops[i].color.alpha != 0xffff)
- {
- flags &= ~FAST_PATH_IS_OPAQUE;
- break;
- }
- }
- }
- break;
-
- default:
- code = PIXMAN_unknown;
- break;
- }
-
- /* Alpha map */
- if (!image->common.alpha_map)
- {
- flags |= FAST_PATH_NO_ALPHA_MAP;
- }
- else
- {
- if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
- flags &= ~FAST_PATH_NARROW_FORMAT;
- }
-
- /* Both alpha maps and convolution filters can introduce
- * non-opaqueness in otherwise opaque images. Also
- * an image with component alpha turned on is only opaque
- * if all channels are opaque, so we simply turn it off
- * unconditionally for those images.
- */
- if (image->common.alpha_map ||
- image->common.filter == PIXMAN_FILTER_CONVOLUTION ||
- image->common.component_alpha)
- {
- flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
- }
-
- image->common.flags = flags;
- image->common.extended_format_code = code;
-}
-
-void
-_pixman_image_validate (pixman_image_t *image)
-{
- if (image->common.dirty)
- {
- compute_image_info (image);
-
- /* It is important that property_changed is
- * called *after* compute_image_info() because
- * property_changed() can make use of the flags
- * to set up accessors etc.
- */
- image->common.property_changed (image);
-
- image->common.dirty = FALSE;
- }
-
- if (image->common.alpha_map)
- _pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_set_clip_region32 (pixman_image_t * image,
- pixman_region32_t *region)
-{
- image_common_t *common = (image_common_t *)image;
- pixman_bool_t result;
-
- if (region)
- {
- if ((result = pixman_region32_copy (&common->clip_region, region)))
- image->common.have_clip_region = TRUE;
- }
- else
- {
- _pixman_image_reset_clip_region (image);
-
- result = TRUE;
- }
-
- image_property_changed (image);
-
- return result;
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_set_clip_region (pixman_image_t * image,
- pixman_region16_t *region)
-{
- image_common_t *common = (image_common_t *)image;
- pixman_bool_t result;
-
- if (region)
- {
- if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
- image->common.have_clip_region = TRUE;
- }
- else
- {
- _pixman_image_reset_clip_region (image);
-
- result = TRUE;
- }
-
- image_property_changed (image);
-
- return result;
-}
-
-PIXMAN_EXPORT void
-pixman_image_set_has_client_clip (pixman_image_t *image,
- pixman_bool_t client_clip)
-{
- image->common.client_clip = client_clip;
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_set_transform (pixman_image_t * image,
- const pixman_transform_t *transform)
-{
- static const pixman_transform_t id =
- {
- { { pixman_fixed_1, 0, 0 },
- { 0, pixman_fixed_1, 0 },
- { 0, 0, pixman_fixed_1 } }
- };
-
- image_common_t *common = (image_common_t *)image;
- pixman_bool_t result;
-
- if (common->transform == transform)
- return TRUE;
-
- if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
- {
- free (common->transform);
- common->transform = NULL;
- result = TRUE;
-
- goto out;
- }
-
- if (common->transform == NULL)
- common->transform = malloc (sizeof (pixman_transform_t));
-
- if (common->transform == NULL)
- {
- result = FALSE;
-
- goto out;
- }
-
- memcpy (common->transform, transform, sizeof(pixman_transform_t));
-
- result = TRUE;
-
-out:
- image_property_changed (image);
-
- return result;
-}
-
-PIXMAN_EXPORT void
-pixman_image_set_repeat (pixman_image_t *image,
- pixman_repeat_t repeat)
-{
- image->common.repeat = repeat;
-
- image_property_changed (image);
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_set_filter (pixman_image_t * image,
- pixman_filter_t filter,
- const pixman_fixed_t *params,
- int n_params)
-{
- image_common_t *common = (image_common_t *)image;
- pixman_fixed_t *new_params;
-
- if (params == common->filter_params && filter == common->filter)
- return TRUE;
-
- new_params = NULL;
- if (params)
- {
- new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
- if (!new_params)
- return FALSE;
-
- memcpy (new_params,
- params, n_params * sizeof (pixman_fixed_t));
- }
-
- common->filter = filter;
-
- if (common->filter_params)
- free (common->filter_params);
-
- common->filter_params = new_params;
- common->n_filter_params = n_params;
-
- image_property_changed (image);
- return TRUE;
-}
-
-PIXMAN_EXPORT void
-pixman_image_set_source_clipping (pixman_image_t *image,
- pixman_bool_t clip_sources)
-{
- image->common.clip_sources = clip_sources;
-
- image_property_changed (image);
-}
-
-/* Unlike all the other property setters, this function does not
- * copy the content of indexed. Doing this copying is simply
- * way, way too expensive.
- */
-PIXMAN_EXPORT void
-pixman_image_set_indexed (pixman_image_t * image,
- const pixman_indexed_t *indexed)
-{
- bits_image_t *bits = (bits_image_t *)image;
-
- bits->indexed = indexed;
-
- image_property_changed (image);
-}
-
-PIXMAN_EXPORT void
-pixman_image_set_alpha_map (pixman_image_t *image,
- pixman_image_t *alpha_map,
- int16_t x,
- int16_t y)
-{
- image_common_t *common = (image_common_t *)image;
-
- return_if_fail (!alpha_map || alpha_map->type == BITS);
-
- if (alpha_map && common->alpha_count > 0)
- {
- /* If this image is being used as an alpha map itself,
- * then you can't give it an alpha map of its own.
- */
- return;
- }
-
- if (alpha_map && alpha_map->common.alpha_map)
- {
- /* If the image has an alpha map of its own,
- * then it can't be used as an alpha map itself
- */
- return;
- }
-
- if (common->alpha_map != (bits_image_t *)alpha_map)
- {
- if (common->alpha_map)
- {
- common->alpha_map->common.alpha_count--;
-
- pixman_image_unref ((pixman_image_t *)common->alpha_map);
- }
-
- if (alpha_map)
- {
- common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
-
- common->alpha_map->common.alpha_count++;
- }
- else
- {
- common->alpha_map = NULL;
- }
- }
-
- common->alpha_origin_x = x;
- common->alpha_origin_y = y;
-
- image_property_changed (image);
-}
-
-PIXMAN_EXPORT void
-pixman_image_set_component_alpha (pixman_image_t *image,
- pixman_bool_t component_alpha)
-{
- image->common.component_alpha = component_alpha;
-
- image_property_changed (image);
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_get_component_alpha (pixman_image_t *image)
-{
- return image->common.component_alpha;
-}
-
-PIXMAN_EXPORT void
-pixman_image_set_accessors (pixman_image_t * image,
- pixman_read_memory_func_t read_func,
- pixman_write_memory_func_t write_func)
-{
- return_if_fail (image != NULL);
-
- if (image->type == BITS)
- {
- image->bits.read_func = read_func;
- image->bits.write_func = write_func;
-
- image_property_changed (image);
- }
-}
-
-PIXMAN_EXPORT uint32_t *
-pixman_image_get_data (pixman_image_t *image)
-{
- if (image->type == BITS)
- return image->bits.bits;
-
- return NULL;
-}
-
-PIXMAN_EXPORT int
-pixman_image_get_width (pixman_image_t *image)
-{
- if (image->type == BITS)
- return image->bits.width;
-
- return 0;
-}
-
-PIXMAN_EXPORT int
-pixman_image_get_height (pixman_image_t *image)
-{
- if (image->type == BITS)
- return image->bits.height;
-
- return 0;
-}
-
-PIXMAN_EXPORT int
-pixman_image_get_stride (pixman_image_t *image)
-{
- if (image->type == BITS)
- return image->bits.rowstride * (int) sizeof (uint32_t);
-
- return 0;
-}
-
-PIXMAN_EXPORT int
-pixman_image_get_depth (pixman_image_t *image)
-{
- if (image->type == BITS)
- return PIXMAN_FORMAT_DEPTH (image->bits.format);
-
- return 0;
-}
-
-PIXMAN_EXPORT pixman_format_code_t
-pixman_image_get_format (pixman_image_t *image)
-{
- if (image->type == BITS)
- return image->bits.format;
-
- return 0;
-}
-
-uint32_t
-_pixman_image_get_solid (pixman_image_t * image,
- pixman_format_code_t format)
-{
- uint32_t result;
-
- _pixman_image_get_scanline_32 (image, 0, 0, 1, &result, NULL);
-
- /* If necessary, convert RGB <--> BGR. */
- if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
- {
- result = (((result & 0xff000000) >> 0) |
- ((result & 0x00ff0000) >> 16) |
- ((result & 0x0000ff00) >> 0) |
- ((result & 0x000000ff) << 16));
- }
-
- return result;
-}
+/* + * Copyright © 2000 SuSE, Inc. + * Copyright © 2007 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "pixman-private.h" +#include "pixman-combine32.h" + +pixman_bool_t +_pixman_init_gradient (gradient_t * gradient, + const pixman_gradient_stop_t *stops, + int n_stops) +{ + return_val_if_fail (n_stops > 0, FALSE); + + gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t)); + if (!gradient->stops) + return FALSE; + + memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t)); + + gradient->n_stops = n_stops; + + return TRUE; +} + +pixman_image_t * +_pixman_image_allocate (void) +{ + pixman_image_t *image = malloc (sizeof (pixman_image_t)); + + if (image) + { + image_common_t *common = &image->common; + + pixman_region32_init (&common->clip_region); + + common->alpha_count = 0; + common->have_clip_region = FALSE; + common->clip_sources = FALSE; + common->transform = NULL; + common->repeat = PIXMAN_REPEAT_NONE; + common->filter = PIXMAN_FILTER_NEAREST; + common->filter_params = NULL; + common->n_filter_params = 0; + common->alpha_map = NULL; + common->component_alpha = FALSE; + common->ref_count = 1; + common->property_changed = NULL; + common->client_clip = FALSE; + common->destroy_func = NULL; + common->destroy_data = NULL; + common->dirty = TRUE; + } + + return image; +} + +static void +image_property_changed (pixman_image_t *image) +{ + image->common.dirty = TRUE; +} + +/* Ref Counting */ +PIXMAN_EXPORT pixman_image_t * +pixman_image_ref (pixman_image_t *image) +{ + image->common.ref_count++; + + return image; +} + +/* returns TRUE when the image is freed */ +PIXMAN_EXPORT pixman_bool_t +pixman_image_unref (pixman_image_t *image) +{ + image_common_t *common = (image_common_t *)image; + + common->ref_count--; + + if (common->ref_count == 0) + { + if (image->common.destroy_func) + image->common.destroy_func (image, image->common.destroy_data); + + pixman_region32_fini (&common->clip_region); + + if (common->transform) + free (common->transform); + + if (common->filter_params) + free (common->filter_params); + + if (common->alpha_map) + pixman_image_unref ((pixman_image_t *)common->alpha_map); + + if (image->type == LINEAR || + image->type == RADIAL || + image->type == CONICAL) + { + if (image->gradient.stops) + free (image->gradient.stops); + } + + if (image->type == BITS && image->bits.free_me) + free (image->bits.free_me); + + free (image); + + return TRUE; + } + + return FALSE; +} + +PIXMAN_EXPORT void +pixman_image_set_destroy_function (pixman_image_t * image, + pixman_image_destroy_func_t func, + void * data) +{ + image->common.destroy_func = func; + image->common.destroy_data = data; +} + +PIXMAN_EXPORT void * +pixman_image_get_destroy_data (pixman_image_t *image) +{ + return image->common.destroy_data; +} + +void +_pixman_image_reset_clip_region (pixman_image_t *image) +{ + image->common.have_clip_region = FALSE; +} + +/* Executive Summary: This function is a no-op that only exists + * for historical reasons. + * + * There used to be a bug in the X server where it would rely on + * out-of-bounds accesses when it was asked to composite with a + * window as the source. It would create a pixman image pointing + * to some bogus position in memory, but then set a clip region + * to the position where the actual bits were. + * + * Due to a bug in old versions of pixman, where it would not clip + * against the image bounds when a clip region was set, this would + * actually work. So when the pixman bug was fixed, a workaround was + * added to allow certain out-of-bound accesses. This function disabled + * those workarounds. + * + * Since 0.21.2, pixman doesn't do these workarounds anymore, so now + * this function is a no-op. + */ +PIXMAN_EXPORT void +pixman_disable_out_of_bounds_workaround (void) +{ +} + +static void +compute_image_info (pixman_image_t *image) +{ + pixman_format_code_t code; + uint32_t flags = 0; + + /* Transform */ + if (!image->common.transform) + { + flags |= (FAST_PATH_ID_TRANSFORM | + FAST_PATH_X_UNIT_POSITIVE | + FAST_PATH_Y_UNIT_ZERO | + FAST_PATH_AFFINE_TRANSFORM); + } + else + { + flags |= FAST_PATH_HAS_TRANSFORM; + + if (image->common.transform->matrix[2][0] == 0 && + image->common.transform->matrix[2][1] == 0 && + image->common.transform->matrix[2][2] == pixman_fixed_1) + { + flags |= FAST_PATH_AFFINE_TRANSFORM; + + if (image->common.transform->matrix[0][1] == 0 && + image->common.transform->matrix[1][0] == 0) + { + flags |= FAST_PATH_SCALE_TRANSFORM; + } + } + + if (image->common.transform->matrix[0][0] > 0) + flags |= FAST_PATH_X_UNIT_POSITIVE; + + if (image->common.transform->matrix[1][0] == 0) + flags |= FAST_PATH_Y_UNIT_ZERO; + } + + /* Filter */ + switch (image->common.filter) + { + case PIXMAN_FILTER_NEAREST: + case PIXMAN_FILTER_FAST: + flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); + break; + + case PIXMAN_FILTER_BILINEAR: + case PIXMAN_FILTER_GOOD: + case PIXMAN_FILTER_BEST: + flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); + break; + + case PIXMAN_FILTER_CONVOLUTION: + break; + + default: + flags |= FAST_PATH_NO_CONVOLUTION_FILTER; + break; + } + + /* Repeat mode */ + switch (image->common.repeat) + { + case PIXMAN_REPEAT_NONE: + flags |= + FAST_PATH_NO_REFLECT_REPEAT | + FAST_PATH_NO_PAD_REPEAT | + FAST_PATH_NO_NORMAL_REPEAT; + break; + + case PIXMAN_REPEAT_REFLECT: + flags |= + FAST_PATH_NO_PAD_REPEAT | + FAST_PATH_NO_NONE_REPEAT | + FAST_PATH_NO_NORMAL_REPEAT; + break; + + case PIXMAN_REPEAT_PAD: + flags |= + FAST_PATH_NO_REFLECT_REPEAT | + FAST_PATH_NO_NONE_REPEAT | + FAST_PATH_NO_NORMAL_REPEAT; + break; + + default: + flags |= + FAST_PATH_NO_REFLECT_REPEAT | + FAST_PATH_NO_PAD_REPEAT | + FAST_PATH_NO_NONE_REPEAT; + break; + } + + /* Component alpha */ + if (image->common.component_alpha) + flags |= FAST_PATH_COMPONENT_ALPHA; + else + flags |= FAST_PATH_UNIFIED_ALPHA; + + flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT); + + /* Type specific checks */ + switch (image->type) + { + case SOLID: + code = PIXMAN_solid; + + if (image->solid.color.alpha == 0xffff) + flags |= FAST_PATH_IS_OPAQUE; + break; + + case BITS: + if (image->bits.width == 1 && + image->bits.height == 1 && + image->common.repeat != PIXMAN_REPEAT_NONE) + { + code = PIXMAN_solid; + } + else + { + code = image->bits.format; + } + + if (!PIXMAN_FORMAT_A (image->bits.format) && + PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY && + PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR) + { + flags |= FAST_PATH_SAMPLES_OPAQUE; + + if (image->common.repeat != PIXMAN_REPEAT_NONE) + flags |= FAST_PATH_IS_OPAQUE; + } + + if (image->bits.read_func || image->bits.write_func) + flags &= ~FAST_PATH_NO_ACCESSORS; + + if (PIXMAN_FORMAT_IS_WIDE (image->bits.format)) + flags &= ~FAST_PATH_NARROW_FORMAT; + break; + + case RADIAL: + code = PIXMAN_unknown; + + /* + * As explained in pixman-radial-gradient.c, every point of + * the plane has a valid associated radius (and thus will be + * colored) if and only if a is negative (i.e. one of the two + * circles contains the other one). + */ + + if (image->radial.a >= 0) + break; + + /* Fall through */ + + case CONICAL: + case LINEAR: + code = PIXMAN_unknown; + + if (image->common.repeat != PIXMAN_REPEAT_NONE) + { + int i; + + flags |= FAST_PATH_IS_OPAQUE; + for (i = 0; i < image->gradient.n_stops; ++i) + { + if (image->gradient.stops[i].color.alpha != 0xffff) + { + flags &= ~FAST_PATH_IS_OPAQUE; + break; + } + } + } + break; + + default: + code = PIXMAN_unknown; + break; + } + + /* Alpha map */ + if (!image->common.alpha_map) + { + flags |= FAST_PATH_NO_ALPHA_MAP; + } + else + { + if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format)) + flags &= ~FAST_PATH_NARROW_FORMAT; + } + + /* Both alpha maps and convolution filters can introduce + * non-opaqueness in otherwise opaque images. Also + * an image with component alpha turned on is only opaque + * if all channels are opaque, so we simply turn it off + * unconditionally for those images. + */ + if (image->common.alpha_map || + image->common.filter == PIXMAN_FILTER_CONVOLUTION || + image->common.component_alpha) + { + flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE); + } + + image->common.flags = flags; + image->common.extended_format_code = code; +} + +void +_pixman_image_validate (pixman_image_t *image) +{ + if (image->common.dirty) + { + compute_image_info (image); + + /* It is important that property_changed is + * called *after* compute_image_info() because + * property_changed() can make use of the flags + * to set up accessors etc. + */ + if (image->common.property_changed) + image->common.property_changed (image); + + image->common.dirty = FALSE; + } + + if (image->common.alpha_map) + _pixman_image_validate ((pixman_image_t *)image->common.alpha_map); +} + +PIXMAN_EXPORT pixman_bool_t +pixman_image_set_clip_region32 (pixman_image_t * image, + pixman_region32_t *region) +{ + image_common_t *common = (image_common_t *)image; + pixman_bool_t result; + + if (region) + { + if ((result = pixman_region32_copy (&common->clip_region, region))) + image->common.have_clip_region = TRUE; + } + else + { + _pixman_image_reset_clip_region (image); + + result = TRUE; + } + + image_property_changed (image); + + return result; +} + +PIXMAN_EXPORT pixman_bool_t +pixman_image_set_clip_region (pixman_image_t * image, + pixman_region16_t *region) +{ + image_common_t *common = (image_common_t *)image; + pixman_bool_t result; + + if (region) + { + if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region))) + image->common.have_clip_region = TRUE; + } + else + { + _pixman_image_reset_clip_region (image); + + result = TRUE; + } + + image_property_changed (image); + + return result; +} + +PIXMAN_EXPORT void +pixman_image_set_has_client_clip (pixman_image_t *image, + pixman_bool_t client_clip) +{ + image->common.client_clip = client_clip; +} + +PIXMAN_EXPORT pixman_bool_t +pixman_image_set_transform (pixman_image_t * image, + const pixman_transform_t *transform) +{ + static const pixman_transform_t id = + { + { { pixman_fixed_1, 0, 0 }, + { 0, pixman_fixed_1, 0 }, + { 0, 0, pixman_fixed_1 } } + }; + + image_common_t *common = (image_common_t *)image; + pixman_bool_t result; + + if (common->transform == transform) + return TRUE; + + if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0) + { + free (common->transform); + common->transform = NULL; + result = TRUE; + + goto out; + } + + if (common->transform == NULL) + common->transform = malloc (sizeof (pixman_transform_t)); + + if (common->transform == NULL) + { + result = FALSE; + + goto out; + } + + memcpy (common->transform, transform, sizeof(pixman_transform_t)); + + result = TRUE; + +out: + image_property_changed (image); + + return result; +} + +PIXMAN_EXPORT void +pixman_image_set_repeat (pixman_image_t *image, + pixman_repeat_t repeat) +{ + image->common.repeat = repeat; + + image_property_changed (image); +} + +PIXMAN_EXPORT pixman_bool_t +pixman_image_set_filter (pixman_image_t * image, + pixman_filter_t filter, + const pixman_fixed_t *params, + int n_params) +{ + image_common_t *common = (image_common_t *)image; + pixman_fixed_t *new_params; + + if (params == common->filter_params && filter == common->filter) + return TRUE; + + new_params = NULL; + if (params) + { + new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t)); + if (!new_params) + return FALSE; + + memcpy (new_params, + params, n_params * sizeof (pixman_fixed_t)); + } + + common->filter = filter; + + if (common->filter_params) + free (common->filter_params); + + common->filter_params = new_params; + common->n_filter_params = n_params; + + image_property_changed (image); + return TRUE; +} + +PIXMAN_EXPORT void +pixman_image_set_source_clipping (pixman_image_t *image, + pixman_bool_t clip_sources) +{ + image->common.clip_sources = clip_sources; + + image_property_changed (image); +} + +/* Unlike all the other property setters, this function does not + * copy the content of indexed. Doing this copying is simply + * way, way too expensive. + */ +PIXMAN_EXPORT void +pixman_image_set_indexed (pixman_image_t * image, + const pixman_indexed_t *indexed) +{ + bits_image_t *bits = (bits_image_t *)image; + + bits->indexed = indexed; + + image_property_changed (image); +} + +PIXMAN_EXPORT void +pixman_image_set_alpha_map (pixman_image_t *image, + pixman_image_t *alpha_map, + int16_t x, + int16_t y) +{ + image_common_t *common = (image_common_t *)image; + + return_if_fail (!alpha_map || alpha_map->type == BITS); + + if (alpha_map && common->alpha_count > 0) + { + /* If this image is being used as an alpha map itself, + * then you can't give it an alpha map of its own. + */ + return; + } + + if (alpha_map && alpha_map->common.alpha_map) + { + /* If the image has an alpha map of its own, + * then it can't be used as an alpha map itself + */ + return; + } + + if (common->alpha_map != (bits_image_t *)alpha_map) + { + if (common->alpha_map) + { + common->alpha_map->common.alpha_count--; + + pixman_image_unref ((pixman_image_t *)common->alpha_map); + } + + if (alpha_map) + { + common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map); + + common->alpha_map->common.alpha_count++; + } + else + { + common->alpha_map = NULL; + } + } + + common->alpha_origin_x = x; + common->alpha_origin_y = y; + + image_property_changed (image); +} + +PIXMAN_EXPORT void +pixman_image_set_component_alpha (pixman_image_t *image, + pixman_bool_t component_alpha) +{ + image->common.component_alpha = component_alpha; + + image_property_changed (image); +} + +PIXMAN_EXPORT pixman_bool_t +pixman_image_get_component_alpha (pixman_image_t *image) +{ + return image->common.component_alpha; +} + +PIXMAN_EXPORT void +pixman_image_set_accessors (pixman_image_t * image, + pixman_read_memory_func_t read_func, + pixman_write_memory_func_t write_func) +{ + return_if_fail (image != NULL); + + if (image->type == BITS) + { + image->bits.read_func = read_func; + image->bits.write_func = write_func; + + image_property_changed (image); + } +} + +PIXMAN_EXPORT uint32_t * +pixman_image_get_data (pixman_image_t *image) +{ + if (image->type == BITS) + return image->bits.bits; + + return NULL; +} + +PIXMAN_EXPORT int +pixman_image_get_width (pixman_image_t *image) +{ + if (image->type == BITS) + return image->bits.width; + + return 0; +} + +PIXMAN_EXPORT int +pixman_image_get_height (pixman_image_t *image) +{ + if (image->type == BITS) + return image->bits.height; + + return 0; +} + +PIXMAN_EXPORT int +pixman_image_get_stride (pixman_image_t *image) +{ + if (image->type == BITS) + return image->bits.rowstride * (int) sizeof (uint32_t); + + return 0; +} + +PIXMAN_EXPORT int +pixman_image_get_depth (pixman_image_t *image) +{ + if (image->type == BITS) + return PIXMAN_FORMAT_DEPTH (image->bits.format); + + return 0; +} + +PIXMAN_EXPORT pixman_format_code_t +pixman_image_get_format (pixman_image_t *image) +{ + if (image->type == BITS) + return image->bits.format; + + return 0; +} + +uint32_t +_pixman_image_get_solid (pixman_implementation_t *imp, + pixman_image_t * image, + pixman_format_code_t format) +{ + uint32_t result; + pixman_iter_t iter; + + _pixman_implementation_src_iter_init ( + imp, &iter, image, 0, 0, 1, 1, + (uint8_t *)&result, ITER_NARROW); + + result = *iter.get_scanline (&iter, NULL); + + /* If necessary, convert RGB <--> BGR. */ + if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB) + { + result = (((result & 0xff000000) >> 0) | + ((result & 0x00ff0000) >> 16) | + ((result & 0x0000ff00) >> 0) | + ((result & 0x000000ff) << 16)); + } + + return result; +} diff --git a/pixman/pixman/pixman-implementation.c b/pixman/pixman/pixman-implementation.c index bc3749ef5..adaf9c61e 100644 --- a/pixman/pixman/pixman-implementation.c +++ b/pixman/pixman/pixman-implementation.c @@ -111,6 +111,36 @@ delegate_fill (pixman_implementation_t *imp, imp->delegate, bits, stride, bpp, x, y, width, height, xor); } +static void +delegate_src_iter_init (pixman_implementation_t *imp, + pixman_iter_t * iter, + pixman_image_t * image, + int x, + int y, + int width, + int height, + uint8_t * buffer, + iter_flags_t flags) +{ + _pixman_implementation_src_iter_init ( + imp->delegate, iter, image, x, y, width, height, buffer, flags); +} + +static void +delegate_dest_iter_init (pixman_implementation_t *imp, + pixman_iter_t * iter, + pixman_image_t * image, + int x, + int y, + int width, + int height, + uint8_t * buffer, + iter_flags_t flags) +{ + _pixman_implementation_dest_iter_init ( + imp->delegate, iter, image, x, y, width, height, buffer, flags); +} + pixman_implementation_t * _pixman_implementation_create (pixman_implementation_t *delegate, const pixman_fast_path_t *fast_paths) @@ -133,6 +163,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate, */ imp->blt = delegate_blt; imp->fill = delegate_fill; + imp->src_iter_init = delegate_src_iter_init; + imp->dest_iter_init = delegate_dest_iter_init; for (i = 0; i < PIXMAN_N_OPERATORS; ++i) { @@ -143,7 +175,7 @@ _pixman_implementation_create (pixman_implementation_t *delegate, } imp->fast_paths = fast_paths; - + return imp; } @@ -225,3 +257,50 @@ _pixman_implementation_fill (pixman_implementation_t *imp, return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor); } +static uint32_t * +get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) +{ + return NULL; +} + +void +_pixman_implementation_src_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags) +{ + if (!image) + { + iter->get_scanline = get_scanline_null; + } + else if ((flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == + (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) + { + iter->get_scanline = _pixman_iter_get_scanline_noop; + } + else + { + (*imp->src_iter_init) ( + imp, iter, image, x, y, width, height, buffer, flags); + } +} + +void +_pixman_implementation_dest_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags) +{ + (*imp->dest_iter_init) ( + imp, iter, image, x, y, width, height, buffer, flags); +} diff --git a/pixman/pixman/pixman-linear-gradient.c b/pixman/pixman/pixman-linear-gradient.c index 1756b4a0e..07303fc03 100644 --- a/pixman/pixman/pixman-linear-gradient.c +++ b/pixman/pixman/pixman-linear-gradient.c @@ -1,260 +1,292 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
-/*
- * Copyright © 2000 SuSE, Inc.
- * Copyright © 2007 Red Hat, Inc.
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- * 2005 Lars Knoll & Zack Rusin, Trolltech
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdlib.h>
-#include "pixman-private.h"
-
-static source_image_class_t
-linear_gradient_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height)
-{
- linear_gradient_t *linear = (linear_gradient_t *)image;
- pixman_vector_t v;
- pixman_fixed_32_32_t l;
- pixman_fixed_48_16_t dx, dy;
- double inc;
- source_image_class_t class;
-
- class = SOURCE_IMAGE_CLASS_UNKNOWN;
-
- if (image->common.transform)
- {
- /* projective transformation */
- if (image->common.transform->matrix[2][0] != 0 ||
- image->common.transform->matrix[2][1] != 0 ||
- image->common.transform->matrix[2][2] == 0)
- {
- return class;
- }
-
- v.vector[0] = image->common.transform->matrix[0][1];
- v.vector[1] = image->common.transform->matrix[1][1];
- v.vector[2] = image->common.transform->matrix[2][2];
- }
- else
- {
- v.vector[0] = 0;
- v.vector[1] = pixman_fixed_1;
- v.vector[2] = pixman_fixed_1;
- }
-
- dx = linear->p2.x - linear->p1.x;
- dy = linear->p2.y - linear->p1.y;
-
- l = dx * dx + dy * dy;
-
- if (l == 0)
- return class;
-
- /*
- * compute how much the input of the gradient walked changes
- * when moving vertically through the whole image
- */
- inc = height * (double) pixman_fixed_1 * pixman_fixed_1 *
- (dx * v.vector[0] + dy * v.vector[1]) /
- (v.vector[2] * (double) l);
-
- /* check that casting to integer would result in 0 */
- if (-1 < inc && inc < 1)
- class = SOURCE_IMAGE_CLASS_HORIZONTAL;
-
- return class;
-}
-
-static void
-linear_gradient_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- pixman_vector_t v, unit;
- pixman_fixed_32_32_t l;
- pixman_fixed_48_16_t dx, dy;
- gradient_t *gradient = (gradient_t *)image;
- linear_gradient_t *linear = (linear_gradient_t *)image;
- uint32_t *end = buffer + width;
- pixman_gradient_walker_t walker;
-
- _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
-
- /* reference point is the center of the pixel */
- v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
- v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
- v.vector[2] = pixman_fixed_1;
-
- if (image->common.transform)
- {
- if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
-
- unit.vector[0] = image->common.transform->matrix[0][0];
- unit.vector[1] = image->common.transform->matrix[1][0];
- unit.vector[2] = image->common.transform->matrix[2][0];
- }
- else
- {
- unit.vector[0] = pixman_fixed_1;
- unit.vector[1] = 0;
- unit.vector[2] = 0;
- }
-
- dx = linear->p2.x - linear->p1.x;
- dy = linear->p2.y - linear->p1.y;
-
- l = dx * dx + dy * dy;
-
- if (l == 0 || unit.vector[2] == 0)
- {
- /* affine transformation only */
- pixman_fixed_32_32_t t, next_inc;
- double inc;
-
- if (l == 0 || v.vector[2] == 0)
- {
- t = 0;
- inc = 0;
- }
- else
- {
- double invden, v2;
-
- invden = pixman_fixed_1 * (double) pixman_fixed_1 /
- (l * (double) v.vector[2]);
- v2 = v.vector[2] * (1. / pixman_fixed_1);
- t = ((dx * v.vector[0] + dy * v.vector[1]) -
- (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
- inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden;
- }
- next_inc = 0;
-
- if (((pixman_fixed_32_32_t )(inc * width)) == 0)
- {
- register uint32_t color;
-
- color = _pixman_gradient_walker_pixel (&walker, t);
- while (buffer < end)
- *buffer++ = color;
- }
- else
- {
- int i;
-
- i = 0;
- while (buffer < end)
- {
- if (!mask || *mask++)
- {
- *buffer = _pixman_gradient_walker_pixel (&walker,
- t + next_inc);
- }
- i++;
- next_inc = inc * i;
- buffer++;
- }
- }
- }
- else
- {
- /* projective transformation */
- double t;
-
- t = 0;
-
- while (buffer < end)
- {
- if (!mask || *mask++)
- {
- if (v.vector[2] != 0)
- {
- double invden, v2;
-
- invden = pixman_fixed_1 * (double) pixman_fixed_1 /
- (l * (double) v.vector[2]);
- v2 = v.vector[2] * (1. / pixman_fixed_1);
- t = ((dx * v.vector[0] + dy * v.vector[1]) -
- (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
- }
-
- *buffer = _pixman_gradient_walker_pixel (&walker, t);
- }
-
- ++buffer;
-
- v.vector[0] += unit.vector[0];
- v.vector[1] += unit.vector[1];
- v.vector[2] += unit.vector[2];
- }
- }
-}
-
-static void
-linear_gradient_property_changed (pixman_image_t *image)
-{
- image->common.get_scanline_32 = linear_gradient_get_scanline_32;
- image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-}
-
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_linear_gradient (pixman_point_fixed_t * p1,
- pixman_point_fixed_t * p2,
- const pixman_gradient_stop_t *stops,
- int n_stops)
-{
- pixman_image_t *image;
- linear_gradient_t *linear;
-
- image = _pixman_image_allocate ();
-
- if (!image)
- return NULL;
-
- linear = &image->linear;
-
- if (!_pixman_init_gradient (&linear->common, stops, n_stops))
- {
- free (image);
- return NULL;
- }
-
- linear->p1 = *p1;
- linear->p2 = *p2;
-
- image->type = LINEAR;
- image->common.classify = linear_gradient_classify;
- image->common.property_changed = linear_gradient_property_changed;
-
- return image;
-}
-
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ +/* + * Copyright © 2000 SuSE, Inc. + * Copyright © 2007 Red Hat, Inc. + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. + * 2005 Lars Knoll & Zack Rusin, Trolltech + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdlib.h> +#include "pixman-private.h" + +static pixman_bool_t +linear_gradient_is_horizontal (pixman_image_t *image, + int x, + int y, + int width, + int height) +{ + linear_gradient_t *linear = (linear_gradient_t *)image; + pixman_vector_t v; + pixman_fixed_32_32_t l; + pixman_fixed_48_16_t dx, dy; + double inc; + + if (image->common.transform) + { + /* projective transformation */ + if (image->common.transform->matrix[2][0] != 0 || + image->common.transform->matrix[2][1] != 0 || + image->common.transform->matrix[2][2] == 0) + { + return FALSE; + } + + v.vector[0] = image->common.transform->matrix[0][1]; + v.vector[1] = image->common.transform->matrix[1][1]; + v.vector[2] = image->common.transform->matrix[2][2]; + } + else + { + v.vector[0] = 0; + v.vector[1] = pixman_fixed_1; + v.vector[2] = pixman_fixed_1; + } + + dx = linear->p2.x - linear->p1.x; + dy = linear->p2.y - linear->p1.y; + + l = dx * dx + dy * dy; + + if (l == 0) + return FALSE; + + /* + * compute how much the input of the gradient walked changes + * when moving vertically through the whole image + */ + inc = height * (double) pixman_fixed_1 * pixman_fixed_1 * + (dx * v.vector[0] + dy * v.vector[1]) / + (v.vector[2] * (double) l); + + /* check that casting to integer would result in 0 */ + if (-1 < inc && inc < 1) + return TRUE; + + return FALSE; +} + +static uint32_t * +linear_get_scanline_narrow (pixman_iter_t *iter, + const uint32_t *mask) +{ + pixman_image_t *image = iter->image; + int x = iter->x; + int y = iter->y; + int width = iter->width; + uint32_t * buffer = iter->buffer; + + pixman_vector_t v, unit; + pixman_fixed_32_32_t l; + pixman_fixed_48_16_t dx, dy; + gradient_t *gradient = (gradient_t *)image; + linear_gradient_t *linear = (linear_gradient_t *)image; + uint32_t *end = buffer + width; + pixman_gradient_walker_t walker; + + _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); + + /* reference point is the center of the pixel */ + v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; + v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; + v.vector[2] = pixman_fixed_1; + + if (image->common.transform) + { + if (!pixman_transform_point_3d (image->common.transform, &v)) + return iter->buffer; + + unit.vector[0] = image->common.transform->matrix[0][0]; + unit.vector[1] = image->common.transform->matrix[1][0]; + unit.vector[2] = image->common.transform->matrix[2][0]; + } + else + { + unit.vector[0] = pixman_fixed_1; + unit.vector[1] = 0; + unit.vector[2] = 0; + } + + dx = linear->p2.x - linear->p1.x; + dy = linear->p2.y - linear->p1.y; + + l = dx * dx + dy * dy; + + if (l == 0 || unit.vector[2] == 0) + { + /* affine transformation only */ + pixman_fixed_32_32_t t, next_inc; + double inc; + + if (l == 0 || v.vector[2] == 0) + { + t = 0; + inc = 0; + } + else + { + double invden, v2; + + invden = pixman_fixed_1 * (double) pixman_fixed_1 / + (l * (double) v.vector[2]); + v2 = v.vector[2] * (1. / pixman_fixed_1); + t = ((dx * v.vector[0] + dy * v.vector[1]) - + (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; + inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; + } + next_inc = 0; + + if (((pixman_fixed_32_32_t )(inc * width)) == 0) + { + register uint32_t color; + + color = _pixman_gradient_walker_pixel (&walker, t); + while (buffer < end) + *buffer++ = color; + } + else + { + int i; + + i = 0; + while (buffer < end) + { + if (!mask || *mask++) + { + *buffer = _pixman_gradient_walker_pixel (&walker, + t + next_inc); + } + i++; + next_inc = inc * i; + buffer++; + } + } + } + else + { + /* projective transformation */ + double t; + + t = 0; + + while (buffer < end) + { + if (!mask || *mask++) + { + if (v.vector[2] != 0) + { + double invden, v2; + + invden = pixman_fixed_1 * (double) pixman_fixed_1 / + (l * (double) v.vector[2]); + v2 = v.vector[2] * (1. / pixman_fixed_1); + t = ((dx * v.vector[0] + dy * v.vector[1]) - + (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; + } + + *buffer = _pixman_gradient_walker_pixel (&walker, t); + } + + ++buffer; + + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } + + iter->y++; + + return iter->buffer; +} + +static uint32_t * +linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + uint32_t *buffer = linear_get_scanline_narrow (iter, NULL); + + pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + + return buffer; +} + +void +_pixman_linear_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags) +{ + if (linear_gradient_is_horizontal (image, x, y, width, height)) + { + if (flags & ITER_NARROW) + linear_get_scanline_narrow (iter, NULL); + else + linear_get_scanline_wide (iter, NULL); + + iter->get_scanline = _pixman_iter_get_scanline_noop; + } + else + { + if (flags & ITER_NARROW) + iter->get_scanline = linear_get_scanline_narrow; + else + iter->get_scanline = linear_get_scanline_wide; + } +} + +PIXMAN_EXPORT pixman_image_t * +pixman_image_create_linear_gradient (pixman_point_fixed_t * p1, + pixman_point_fixed_t * p2, + const pixman_gradient_stop_t *stops, + int n_stops) +{ + pixman_image_t *image; + linear_gradient_t *linear; + + image = _pixman_image_allocate (); + + if (!image) + return NULL; + + linear = &image->linear; + + if (!_pixman_init_gradient (&linear->common, stops, n_stops)) + { + free (image); + return NULL; + } + + linear->p1 = *p1; + linear->p2 = *p2; + + image->type = LINEAR; + + return image; +} + diff --git a/pixman/pixman/pixman-mmx.c b/pixman/pixman/pixman-mmx.c index d05a185ea..6daa364fb 100644 --- a/pixman/pixman/pixman-mmx.c +++ b/pixman/pixman/pixman-mmx.c @@ -1,3378 +1,3378 @@ -/*
- * Copyright © 2004, 2005 Red Hat, Inc.
- * Copyright © 2004 Nicholas Miell
- * Copyright © 2005 Trolltech AS
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Red Hat not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Red Hat makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- *
- * Author: Søren Sandmann (sandmann@redhat.com)
- * Minor Improvements: Nicholas Miell (nmiell@gmail.com)
- * MMX code paths for fbcompose.c by Lars Knoll (lars@trolltech.com)
- *
- * Based on work by Owen Taylor
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef USE_MMX
-
-#include <mmintrin.h>
-#include "pixman-private.h"
-#include "pixman-combine32.h"
-
-#define no_vERBOSE
-
-#ifdef VERBOSE
-#define CHECKPOINT() error_f ("at %s %d\n", __FUNCTION__, __LINE__)
-#else
-#define CHECKPOINT()
-#endif
-
-/* Notes about writing mmx code
- *
- * give memory operands as the second operand. If you give it as the
- * first, gcc will first load it into a register, then use that
- * register
- *
- * ie. use
- *
- * _mm_mullo_pi16 (x, mmx_constant);
- *
- * not
- *
- * _mm_mullo_pi16 (mmx_constant, x);
- *
- * Also try to minimize dependencies. i.e. when you need a value, try
- * to calculate it from a value that was calculated as early as
- * possible.
- */
-
-/* --------------- MMX primitives ------------------------------------- */
-
-#ifdef __GNUC__
-typedef uint64_t mmxdatafield;
-#else
-typedef __m64 mmxdatafield;
-/* If __m64 is defined as a struct or union, define M64_MEMBER to be the
- name of the member used to access the data */
-# ifdef _MSC_VER
-# define M64_MEMBER m64_u64
-# elif defined(__SUNPRO_C)
-# define M64_MEMBER l_
-# endif
-#endif
-
-typedef struct
-{
- mmxdatafield mmx_4x00ff;
- mmxdatafield mmx_4x0080;
- mmxdatafield mmx_565_rgb;
- mmxdatafield mmx_565_unpack_multiplier;
- mmxdatafield mmx_565_r;
- mmxdatafield mmx_565_g;
- mmxdatafield mmx_565_b;
- mmxdatafield mmx_mask_0;
- mmxdatafield mmx_mask_1;
- mmxdatafield mmx_mask_2;
- mmxdatafield mmx_mask_3;
- mmxdatafield mmx_full_alpha;
- mmxdatafield mmx_ffff0000ffff0000;
- mmxdatafield mmx_0000ffff00000000;
- mmxdatafield mmx_000000000000ffff;
-} mmx_data_t;
-
-#if defined(_MSC_VER)
-# define MMXDATA_INIT(field, val) { val ## UI64 }
-#elif defined(M64_MEMBER) /* __m64 is a struct, not an integral type */
-# define MMXDATA_INIT(field, val) field = { val ## ULL }
-#else /* __m64 is an integral type */
-# define MMXDATA_INIT(field, val) field = val ## ULL
-#endif
-
-static const mmx_data_t c =
-{
- MMXDATA_INIT (.mmx_4x00ff, 0x00ff00ff00ff00ff),
- MMXDATA_INIT (.mmx_4x0080, 0x0080008000800080),
- MMXDATA_INIT (.mmx_565_rgb, 0x000001f0003f001f),
- MMXDATA_INIT (.mmx_565_unpack_multiplier, 0x0000008404100840),
- MMXDATA_INIT (.mmx_565_r, 0x000000f800000000),
- MMXDATA_INIT (.mmx_565_g, 0x0000000000fc0000),
- MMXDATA_INIT (.mmx_565_b, 0x00000000000000f8),
- MMXDATA_INIT (.mmx_mask_0, 0xffffffffffff0000),
- MMXDATA_INIT (.mmx_mask_1, 0xffffffff0000ffff),
- MMXDATA_INIT (.mmx_mask_2, 0xffff0000ffffffff),
- MMXDATA_INIT (.mmx_mask_3, 0x0000ffffffffffff),
- MMXDATA_INIT (.mmx_full_alpha, 0x00ff000000000000),
- MMXDATA_INIT (.mmx_ffff0000ffff0000, 0xffff0000ffff0000),
- MMXDATA_INIT (.mmx_0000ffff00000000, 0x0000ffff00000000),
- MMXDATA_INIT (.mmx_000000000000ffff, 0x000000000000ffff),
-};
-
-#ifdef __GNUC__
-# ifdef __ICC
-# define MC(x) to_m64 (c.mmx_ ## x)
-# else
-# define MC(x) ((__m64)c.mmx_ ## x)
-# endif
-#else
-# define MC(x) c.mmx_ ## x
-#endif
-
-static force_inline __m64
-to_m64 (uint64_t x)
-{
-#ifdef __ICC
- return _mm_cvtsi64_m64 (x);
-#elif defined M64_MEMBER /* __m64 is a struct, not an integral type */
- __m64 res;
-
- res.M64_MEMBER = x;
- return res;
-#else /* __m64 is an integral type */
- return (__m64)x;
-#endif
-}
-
-static force_inline uint64_t
-to_uint64 (__m64 x)
-{
-#ifdef __ICC
- return _mm_cvtm64_si64 (x);
-#elif defined M64_MEMBER /* __m64 is a struct, not an integral type */
- uint64_t res = x.M64_MEMBER;
- return res;
-#else /* __m64 is an integral type */
- return (uint64_t)x;
-#endif
-}
-
-static force_inline __m64
-shift (__m64 v,
- int s)
-{
- if (s > 0)
- return _mm_slli_si64 (v, s);
- else if (s < 0)
- return _mm_srli_si64 (v, -s);
- else
- return v;
-}
-
-static force_inline __m64
-negate (__m64 mask)
-{
- return _mm_xor_si64 (mask, MC (4x00ff));
-}
-
-static force_inline __m64
-pix_multiply (__m64 a, __m64 b)
-{
- __m64 res;
-
- res = _mm_mullo_pi16 (a, b);
- res = _mm_adds_pu16 (res, MC (4x0080));
- res = _mm_adds_pu16 (res, _mm_srli_pi16 (res, 8));
- res = _mm_srli_pi16 (res, 8);
-
- return res;
-}
-
-static force_inline __m64
-pix_add (__m64 a, __m64 b)
-{
- return _mm_adds_pu8 (a, b);
-}
-
-static force_inline __m64
-expand_alpha (__m64 pixel)
-{
- __m64 t1, t2;
-
- t1 = shift (pixel, -48);
- t2 = shift (t1, 16);
- t1 = _mm_or_si64 (t1, t2);
- t2 = shift (t1, 32);
- t1 = _mm_or_si64 (t1, t2);
-
- return t1;
-}
-
-static force_inline __m64
-expand_alpha_rev (__m64 pixel)
-{
- __m64 t1, t2;
-
- /* move alpha to low 16 bits and zero the rest */
- t1 = shift (pixel, 48);
- t1 = shift (t1, -48);
-
- t2 = shift (t1, 16);
- t1 = _mm_or_si64 (t1, t2);
- t2 = shift (t1, 32);
- t1 = _mm_or_si64 (t1, t2);
-
- return t1;
-}
-
-static force_inline __m64
-invert_colors (__m64 pixel)
-{
- __m64 x, y, z;
-
- x = y = z = pixel;
-
- x = _mm_and_si64 (x, MC (ffff0000ffff0000));
- y = _mm_and_si64 (y, MC (000000000000ffff));
- z = _mm_and_si64 (z, MC (0000ffff00000000));
-
- y = shift (y, 32);
- z = shift (z, -32);
-
- x = _mm_or_si64 (x, y);
- x = _mm_or_si64 (x, z);
-
- return x;
-}
-
-static force_inline __m64
-over (__m64 src,
- __m64 srca,
- __m64 dest)
-{
- return _mm_adds_pu8 (src, pix_multiply (dest, negate (srca)));
-}
-
-static force_inline __m64
-over_rev_non_pre (__m64 src, __m64 dest)
-{
- __m64 srca = expand_alpha (src);
- __m64 srcfaaa = _mm_or_si64 (srca, MC (full_alpha));
-
- return over (pix_multiply (invert_colors (src), srcfaaa), srca, dest);
-}
-
-static force_inline __m64
-in (__m64 src, __m64 mask)
-{
- return pix_multiply (src, mask);
-}
-
-static force_inline __m64
-in_over_full_src_alpha (__m64 src, __m64 mask, __m64 dest)
-{
- src = _mm_or_si64 (src, MC (full_alpha));
-
- return over (in (src, mask), mask, dest);
-}
-
-#ifndef _MSC_VER
-static force_inline __m64
-in_over (__m64 src, __m64 srca, __m64 mask, __m64 dest)
-{
- return over (in (src, mask), pix_multiply (srca, mask), dest);
-}
-
-#else
-
-#define in_over(src, srca, mask, dest) \
- over (in (src, mask), pix_multiply (srca, mask), dest)
-
-#endif
-
-static force_inline __m64
-load8888 (uint32_t v)
-{
- return _mm_unpacklo_pi8 (_mm_cvtsi32_si64 (v), _mm_setzero_si64 ());
-}
-
-static force_inline __m64
-pack8888 (__m64 lo, __m64 hi)
-{
- return _mm_packs_pu16 (lo, hi);
-}
-
-static force_inline uint32_t
-store8888 (__m64 v)
-{
- return _mm_cvtsi64_si32 (pack8888 (v, _mm_setzero_si64 ()));
-}
-
-/* Expand 16 bits positioned at @pos (0-3) of a mmx register into
- *
- * 00RR00GG00BB
- *
- * --- Expanding 565 in the low word ---
- *
- * m = (m << (32 - 3)) | (m << (16 - 5)) | m;
- * m = m & (01f0003f001f);
- * m = m * (008404100840);
- * m = m >> 8;
- *
- * Note the trick here - the top word is shifted by another nibble to
- * avoid it bumping into the middle word
- */
-static force_inline __m64
-expand565 (__m64 pixel, int pos)
-{
- __m64 p = pixel;
- __m64 t1, t2;
-
- /* move pixel to low 16 bit and zero the rest */
- p = shift (shift (p, (3 - pos) * 16), -48);
-
- t1 = shift (p, 36 - 11);
- t2 = shift (p, 16 - 5);
-
- p = _mm_or_si64 (t1, p);
- p = _mm_or_si64 (t2, p);
- p = _mm_and_si64 (p, MC (565_rgb));
-
- pixel = _mm_mullo_pi16 (p, MC (565_unpack_multiplier));
- return _mm_srli_pi16 (pixel, 8);
-}
-
-static force_inline __m64
-expand8888 (__m64 in, int pos)
-{
- if (pos == 0)
- return _mm_unpacklo_pi8 (in, _mm_setzero_si64 ());
- else
- return _mm_unpackhi_pi8 (in, _mm_setzero_si64 ());
-}
-
-static force_inline __m64
-expandx888 (__m64 in, int pos)
-{
- return _mm_or_si64 (expand8888 (in, pos), MC (full_alpha));
-}
-
-static force_inline __m64
-pack_565 (__m64 pixel, __m64 target, int pos)
-{
- __m64 p = pixel;
- __m64 t = target;
- __m64 r, g, b;
-
- r = _mm_and_si64 (p, MC (565_r));
- g = _mm_and_si64 (p, MC (565_g));
- b = _mm_and_si64 (p, MC (565_b));
-
- r = shift (r, -(32 - 8) + pos * 16);
- g = shift (g, -(16 - 3) + pos * 16);
- b = shift (b, -(0 + 3) + pos * 16);
-
- if (pos == 0)
- t = _mm_and_si64 (t, MC (mask_0));
- else if (pos == 1)
- t = _mm_and_si64 (t, MC (mask_1));
- else if (pos == 2)
- t = _mm_and_si64 (t, MC (mask_2));
- else if (pos == 3)
- t = _mm_and_si64 (t, MC (mask_3));
-
- p = _mm_or_si64 (r, t);
- p = _mm_or_si64 (g, p);
-
- return _mm_or_si64 (b, p);
-}
-
-#ifndef _MSC_VER
-
-static force_inline __m64
-pix_add_mul (__m64 x, __m64 a, __m64 y, __m64 b)
-{
- x = pix_multiply (x, a);
- y = pix_multiply (y, b);
-
- return pix_add (x, y);
-}
-
-#else
-
-#define pix_add_mul(x, a, y, b) \
- ( x = pix_multiply (x, a), \
- y = pix_multiply (y, a), \
- pix_add (x, y) )
-
-#endif
-
-/* --------------- MMX code patch for fbcompose.c --------------------- */
-
-static force_inline uint32_t
-combine (const uint32_t *src, const uint32_t *mask)
-{
- uint32_t ssrc = *src;
-
- if (mask)
- {
- __m64 m = load8888 (*mask);
- __m64 s = load8888 (ssrc);
-
- m = expand_alpha (m);
- s = pix_multiply (s, m);
-
- ssrc = store8888 (s);
- }
-
- return ssrc;
-}
-
-static void
-mmx_combine_over_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- uint32_t ssrc = combine (src, mask);
- uint32_t a = ssrc >> 24;
-
- if (a == 0xff)
- {
- *dest = ssrc;
- }
- else if (ssrc)
- {
- __m64 s, sa;
- s = load8888 (ssrc);
- sa = expand_alpha (s);
- *dest = store8888 (over (s, sa, load8888 (*dest)));
- }
-
- ++dest;
- ++src;
- if (mask)
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_over_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 d, da;
- uint32_t s = combine (src, mask);
-
- d = load8888 (*dest);
- da = expand_alpha (d);
- *dest = store8888 (over (d, da, load8888 (s)));
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_in_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 x, a;
-
- x = load8888 (combine (src, mask));
- a = load8888 (*dest);
- a = expand_alpha (a);
- x = pix_multiply (x, a);
-
- *dest = store8888 (x);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_in_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 x, a;
-
- x = load8888 (*dest);
- a = load8888 (combine (src, mask));
- a = expand_alpha (a);
- x = pix_multiply (x, a);
- *dest = store8888 (x);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_out_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 x, a;
-
- x = load8888 (combine (src, mask));
- a = load8888 (*dest);
- a = expand_alpha (a);
- a = negate (a);
- x = pix_multiply (x, a);
- *dest = store8888 (x);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_out_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 x, a;
-
- x = load8888 (*dest);
- a = load8888 (combine (src, mask));
- a = expand_alpha (a);
- a = negate (a);
- x = pix_multiply (x, a);
-
- *dest = store8888 (x);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_atop_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 s, da, d, sia;
-
- s = load8888 (combine (src, mask));
- d = load8888 (*dest);
- sia = expand_alpha (s);
- sia = negate (sia);
- da = expand_alpha (d);
- s = pix_add_mul (s, da, d, sia);
- *dest = store8888 (s);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_atop_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end;
-
- end = dest + width;
-
- while (dest < end)
- {
- __m64 s, dia, d, sa;
-
- s = load8888 (combine (src, mask));
- d = load8888 (*dest);
- sa = expand_alpha (s);
- dia = expand_alpha (d);
- dia = negate (dia);
- s = pix_add_mul (s, dia, d, sa);
- *dest = store8888 (s);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_xor_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 s, dia, d, sia;
-
- s = load8888 (combine (src, mask));
- d = load8888 (*dest);
- sia = expand_alpha (s);
- dia = expand_alpha (d);
- sia = negate (sia);
- dia = negate (dia);
- s = pix_add_mul (s, dia, d, sia);
- *dest = store8888 (s);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_add_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- __m64 s, d;
-
- s = load8888 (combine (src, mask));
- d = load8888 (*dest);
- s = pix_add (s, d);
- *dest = store8888 (s);
-
- ++dest;
- ++src;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_saturate_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = dest + width;
-
- while (dest < end)
- {
- uint32_t s = combine (src, mask);
- uint32_t d = *dest;
- __m64 ms = load8888 (s);
- __m64 md = load8888 (d);
- uint32_t sa = s >> 24;
- uint32_t da = ~d >> 24;
-
- if (sa > da)
- {
- __m64 msa = load8888 (DIV_UN8 (da, sa) << 24);
- msa = expand_alpha (msa);
- ms = pix_multiply (ms, msa);
- }
-
- md = pix_add (md, ms);
- *dest = store8888 (md);
-
- ++src;
- ++dest;
- if (mask)
- mask++;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_src_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
-
- s = pix_multiply (s, a);
- *dest = store8888 (s);
-
- ++src;
- ++mask;
- ++dest;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_over_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 sa = expand_alpha (s);
-
- *dest = store8888 (in_over (s, sa, a, d));
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_over_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 da = expand_alpha (d);
-
- *dest = store8888 (over (d, da, in (s, a)));
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_in_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 da = expand_alpha (d);
-
- s = pix_multiply (s, a);
- s = pix_multiply (s, da);
- *dest = store8888 (s);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_in_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 sa = expand_alpha (s);
-
- a = pix_multiply (a, sa);
- d = pix_multiply (d, a);
- *dest = store8888 (d);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_out_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 da = expand_alpha (d);
-
- da = negate (da);
- s = pix_multiply (s, a);
- s = pix_multiply (s, da);
- *dest = store8888 (s);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_out_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 sa = expand_alpha (s);
-
- a = pix_multiply (a, sa);
- a = negate (a);
- d = pix_multiply (d, a);
- *dest = store8888 (d);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_atop_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 da = expand_alpha (d);
- __m64 sa = expand_alpha (s);
-
- s = pix_multiply (s, a);
- a = pix_multiply (a, sa);
- a = negate (a);
- d = pix_add_mul (d, a, s, da);
- *dest = store8888 (d);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_atop_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 da = expand_alpha (d);
- __m64 sa = expand_alpha (s);
-
- s = pix_multiply (s, a);
- a = pix_multiply (a, sa);
- da = negate (da);
- d = pix_add_mul (d, a, s, da);
- *dest = store8888 (d);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_xor_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
- __m64 da = expand_alpha (d);
- __m64 sa = expand_alpha (s);
-
- s = pix_multiply (s, a);
- a = pix_multiply (a, sa);
- da = negate (da);
- a = negate (a);
- d = pix_add_mul (d, a, s, da);
- *dest = store8888 (d);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-static void
-mmx_combine_add_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- const uint32_t *end = src + width;
-
- while (src < end)
- {
- __m64 a = load8888 (*mask);
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dest);
-
- s = pix_multiply (s, a);
- d = pix_add (s, d);
- *dest = store8888 (d);
-
- ++src;
- ++dest;
- ++mask;
- }
- _mm_empty ();
-}
-
-/* ------------- MMX code paths called from fbpict.c -------------------- */
-
-static void
-mmx_composite_over_n_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t src;
- uint32_t *dst_line, *dst;
- int32_t w;
- int dst_stride;
- __m64 vsrc, vsrca;
-
- CHECKPOINT ();
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- if (src == 0)
- return;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- w = width;
-
- CHECKPOINT ();
-
- while (w && (unsigned long)dst & 7)
- {
- *dst = store8888 (over (vsrc, vsrca, load8888 (*dst)));
-
- w--;
- dst++;
- }
-
- while (w >= 2)
- {
- __m64 vdest;
- __m64 dest0, dest1;
-
- vdest = *(__m64 *)dst;
-
- dest0 = over (vsrc, vsrca, expand8888 (vdest, 0));
- dest1 = over (vsrc, vsrca, expand8888 (vdest, 1));
-
- *(__m64 *)dst = pack8888 (dest0, dest1);
-
- dst += 2;
- w -= 2;
- }
-
- CHECKPOINT ();
-
- while (w)
- {
- *dst = store8888 (over (vsrc, vsrca, load8888 (*dst)));
-
- w--;
- dst++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_n_0565 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t src;
- uint16_t *dst_line, *dst;
- int32_t w;
- int dst_stride;
- __m64 vsrc, vsrca;
-
- CHECKPOINT ();
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- if (src == 0)
- return;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- w = width;
-
- CHECKPOINT ();
-
- while (w && (unsigned long)dst & 7)
- {
- uint64_t d = *dst;
- __m64 vdest = expand565 (to_m64 (d), 0);
-
- vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0);
- *dst = to_uint64 (vdest);
-
- w--;
- dst++;
- }
-
- while (w >= 4)
- {
- __m64 vdest;
-
- vdest = *(__m64 *)dst;
-
- vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 0)), vdest, 0);
- vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 1)), vdest, 1);
- vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 2)), vdest, 2);
- vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 3)), vdest, 3);
-
- *(__m64 *)dst = vdest;
-
- dst += 4;
- w -= 4;
- }
-
- CHECKPOINT ();
-
- while (w)
- {
- uint64_t d = *dst;
- __m64 vdest = expand565 (to_m64 (d), 0);
-
- vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0);
- *dst = to_uint64 (vdest);
-
- w--;
- dst++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t src, srca;
- uint32_t *dst_line;
- uint32_t *mask_line;
- int dst_stride, mask_stride;
- __m64 vsrc, vsrca;
-
- CHECKPOINT ();
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- srca = src >> 24;
- if (src == 0)
- return;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- int twidth = width;
- uint32_t *p = (uint32_t *)mask_line;
- uint32_t *q = (uint32_t *)dst_line;
-
- while (twidth && (unsigned long)q & 7)
- {
- uint32_t m = *(uint32_t *)p;
-
- if (m)
- {
- __m64 vdest = load8888 (*q);
- vdest = in_over (vsrc, vsrca, load8888 (m), vdest);
- *q = store8888 (vdest);
- }
-
- twidth--;
- p++;
- q++;
- }
-
- while (twidth >= 2)
- {
- uint32_t m0, m1;
- m0 = *p;
- m1 = *(p + 1);
-
- if (m0 | m1)
- {
- __m64 dest0, dest1;
- __m64 vdest = *(__m64 *)q;
-
- dest0 = in_over (vsrc, vsrca, load8888 (m0),
- expand8888 (vdest, 0));
- dest1 = in_over (vsrc, vsrca, load8888 (m1),
- expand8888 (vdest, 1));
-
- *(__m64 *)q = pack8888 (dest0, dest1);
- }
-
- p += 2;
- q += 2;
- twidth -= 2;
- }
-
- while (twidth)
- {
- uint32_t m = *(uint32_t *)p;
-
- if (m)
- {
- __m64 vdest = load8888 (*q);
- vdest = in_over (vsrc, vsrca, load8888 (m), vdest);
- *q = store8888 (vdest);
- }
-
- twidth--;
- p++;
- q++;
- }
-
- dst_line += dst_stride;
- mask_line += mask_stride;
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_8888_n_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t *dst_line, *dst;
- uint32_t *src_line, *src;
- uint32_t mask;
- __m64 vmask;
- int dst_stride, src_stride;
- int32_t w;
- __m64 srca;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
-
- mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);
- mask &= 0xff000000;
- mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
- vmask = load8888 (mask);
- srca = MC (4x00ff);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- while (w && (unsigned long)dst & 7)
- {
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (in_over (s, expand_alpha (s), vmask, d));
-
- w--;
- dst++;
- src++;
- }
-
- while (w >= 2)
- {
- __m64 vs = *(__m64 *)src;
- __m64 vd = *(__m64 *)dst;
- __m64 vsrc0 = expand8888 (vs, 0);
- __m64 vsrc1 = expand8888 (vs, 1);
-
- *(__m64 *)dst = pack8888 (
- in_over (vsrc0, expand_alpha (vsrc0), vmask, expand8888 (vd, 0)),
- in_over (vsrc1, expand_alpha (vsrc1), vmask, expand8888 (vd, 1)));
-
- w -= 2;
- dst += 2;
- src += 2;
- }
-
- while (w)
- {
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (in_over (s, expand_alpha (s), vmask, d));
-
- w--;
- dst++;
- src++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_x888_n_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t *dst_line, *dst;
- uint32_t *src_line, *src;
- uint32_t mask;
- __m64 vmask;
- int dst_stride, src_stride;
- int32_t w;
- __m64 srca;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
- mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);
-
- mask &= 0xff000000;
- mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
- vmask = load8888 (mask);
- srca = MC (4x00ff);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- while (w && (unsigned long)dst & 7)
- {
- __m64 s = load8888 (*src | 0xff000000);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (in_over (s, srca, vmask, d));
-
- w--;
- dst++;
- src++;
- }
-
- while (w >= 16)
- {
- __m64 vd0 = *(__m64 *)(dst + 0);
- __m64 vd1 = *(__m64 *)(dst + 2);
- __m64 vd2 = *(__m64 *)(dst + 4);
- __m64 vd3 = *(__m64 *)(dst + 6);
- __m64 vd4 = *(__m64 *)(dst + 8);
- __m64 vd5 = *(__m64 *)(dst + 10);
- __m64 vd6 = *(__m64 *)(dst + 12);
- __m64 vd7 = *(__m64 *)(dst + 14);
-
- __m64 vs0 = *(__m64 *)(src + 0);
- __m64 vs1 = *(__m64 *)(src + 2);
- __m64 vs2 = *(__m64 *)(src + 4);
- __m64 vs3 = *(__m64 *)(src + 6);
- __m64 vs4 = *(__m64 *)(src + 8);
- __m64 vs5 = *(__m64 *)(src + 10);
- __m64 vs6 = *(__m64 *)(src + 12);
- __m64 vs7 = *(__m64 *)(src + 14);
-
- vd0 = pack8888 (
- in_over (expandx888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)),
- in_over (expandx888 (vs0, 1), srca, vmask, expand8888 (vd0, 1)));
-
- vd1 = pack8888 (
- in_over (expandx888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)),
- in_over (expandx888 (vs1, 1), srca, vmask, expand8888 (vd1, 1)));
-
- vd2 = pack8888 (
- in_over (expandx888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)),
- in_over (expandx888 (vs2, 1), srca, vmask, expand8888 (vd2, 1)));
-
- vd3 = pack8888 (
- in_over (expandx888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)),
- in_over (expandx888 (vs3, 1), srca, vmask, expand8888 (vd3, 1)));
-
- vd4 = pack8888 (
- in_over (expandx888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)),
- in_over (expandx888 (vs4, 1), srca, vmask, expand8888 (vd4, 1)));
-
- vd5 = pack8888 (
- in_over (expandx888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)),
- in_over (expandx888 (vs5, 1), srca, vmask, expand8888 (vd5, 1)));
-
- vd6 = pack8888 (
- in_over (expandx888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)),
- in_over (expandx888 (vs6, 1), srca, vmask, expand8888 (vd6, 1)));
-
- vd7 = pack8888 (
- in_over (expandx888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)),
- in_over (expandx888 (vs7, 1), srca, vmask, expand8888 (vd7, 1)));
-
- *(__m64 *)(dst + 0) = vd0;
- *(__m64 *)(dst + 2) = vd1;
- *(__m64 *)(dst + 4) = vd2;
- *(__m64 *)(dst + 6) = vd3;
- *(__m64 *)(dst + 8) = vd4;
- *(__m64 *)(dst + 10) = vd5;
- *(__m64 *)(dst + 12) = vd6;
- *(__m64 *)(dst + 14) = vd7;
-
- w -= 16;
- dst += 16;
- src += 16;
- }
-
- while (w)
- {
- __m64 s = load8888 (*src | 0xff000000);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (in_over (s, srca, vmask, d));
-
- w--;
- dst++;
- src++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_8888_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t *dst_line, *dst;
- uint32_t *src_line, *src;
- uint32_t s;
- int dst_stride, src_stride;
- uint8_t a;
- int32_t w;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- while (w--)
- {
- s = *src++;
- a = s >> 24;
-
- if (a == 0xff)
- {
- *dst = s;
- }
- else if (s)
- {
- __m64 ms, sa;
- ms = load8888 (s);
- sa = expand_alpha (ms);
- *dst = store8888 (over (ms, sa, load8888 (*dst)));
- }
-
- dst++;
- }
- }
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_8888_0565 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint16_t *dst_line, *dst;
- uint32_t *src_line, *src;
- int dst_stride, src_stride;
- int32_t w;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
-
-#if 0
- /* FIXME */
- assert (src_image->drawable == mask_image->drawable);
-#endif
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- CHECKPOINT ();
-
- while (w && (unsigned long)dst & 7)
- {
- __m64 vsrc = load8888 (*src);
- uint64_t d = *dst;
- __m64 vdest = expand565 (to_m64 (d), 0);
-
- vdest = pack_565 (
- over (vsrc, expand_alpha (vsrc), vdest), vdest, 0);
-
- *dst = to_uint64 (vdest);
-
- w--;
- dst++;
- src++;
- }
-
- CHECKPOINT ();
-
- while (w >= 4)
- {
- __m64 vsrc0, vsrc1, vsrc2, vsrc3;
- __m64 vdest;
-
- vsrc0 = load8888 (*(src + 0));
- vsrc1 = load8888 (*(src + 1));
- vsrc2 = load8888 (*(src + 2));
- vsrc3 = load8888 (*(src + 3));
-
- vdest = *(__m64 *)dst;
-
- vdest = pack_565 (over (vsrc0, expand_alpha (vsrc0), expand565 (vdest, 0)), vdest, 0);
- vdest = pack_565 (over (vsrc1, expand_alpha (vsrc1), expand565 (vdest, 1)), vdest, 1);
- vdest = pack_565 (over (vsrc2, expand_alpha (vsrc2), expand565 (vdest, 2)), vdest, 2);
- vdest = pack_565 (over (vsrc3, expand_alpha (vsrc3), expand565 (vdest, 3)), vdest, 3);
-
- *(__m64 *)dst = vdest;
-
- w -= 4;
- dst += 4;
- src += 4;
- }
-
- CHECKPOINT ();
-
- while (w)
- {
- __m64 vsrc = load8888 (*src);
- uint64_t d = *dst;
- __m64 vdest = expand565 (to_m64 (d), 0);
-
- vdest = pack_565 (over (vsrc, expand_alpha (vsrc), vdest), vdest, 0);
-
- *dst = to_uint64 (vdest);
-
- w--;
- dst++;
- src++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t src, srca;
- uint32_t *dst_line, *dst;
- uint8_t *mask_line, *mask;
- int dst_stride, mask_stride;
- int32_t w;
- __m64 vsrc, vsrca;
- uint64_t srcsrc;
-
- CHECKPOINT ();
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- srca = src >> 24;
- if (src == 0)
- return;
-
- srcsrc = (uint64_t)src << 32 | src;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- mask = mask_line;
- mask_line += mask_stride;
- w = width;
-
- CHECKPOINT ();
-
- while (w && (unsigned long)dst & 7)
- {
- uint64_t m = *mask;
-
- if (m)
- {
- __m64 vdest = in_over (vsrc, vsrca,
- expand_alpha_rev (to_m64 (m)),
- load8888 (*dst));
-
- *dst = store8888 (vdest);
- }
-
- w--;
- mask++;
- dst++;
- }
-
- CHECKPOINT ();
-
- while (w >= 2)
- {
- uint64_t m0, m1;
-
- m0 = *mask;
- m1 = *(mask + 1);
-
- if (srca == 0xff && (m0 & m1) == 0xff)
- {
- *(uint64_t *)dst = srcsrc;
- }
- else if (m0 | m1)
- {
- __m64 vdest;
- __m64 dest0, dest1;
-
- vdest = *(__m64 *)dst;
-
- dest0 = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m0)),
- expand8888 (vdest, 0));
- dest1 = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m1)),
- expand8888 (vdest, 1));
-
- *(__m64 *)dst = pack8888 (dest0, dest1);
- }
-
- mask += 2;
- dst += 2;
- w -= 2;
- }
-
- CHECKPOINT ();
-
- while (w)
- {
- uint64_t m = *mask;
-
- if (m)
- {
- __m64 vdest = load8888 (*dst);
-
- vdest = in_over (
- vsrc, vsrca, expand_alpha_rev (to_m64 (m)), vdest);
- *dst = store8888 (vdest);
- }
-
- w--;
- mask++;
- dst++;
- }
- }
-
- _mm_empty ();
-}
-
-pixman_bool_t
-pixman_fill_mmx (uint32_t *bits,
- int stride,
- int bpp,
- int x,
- int y,
- int width,
- int height,
- uint32_t xor)
-{
- uint64_t fill;
- __m64 vfill;
- uint32_t byte_width;
- uint8_t *byte_line;
-
-#ifdef __GNUC__
- __m64 v1, v2, v3, v4, v5, v6, v7;
-#endif
-
- if (bpp != 16 && bpp != 32 && bpp != 8)
- return FALSE;
-
- if (bpp == 8)
- {
- stride = stride * (int) sizeof (uint32_t) / 1;
- byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x);
- byte_width = width;
- stride *= 1;
- xor = (xor & 0xff) * 0x01010101;
- }
- else if (bpp == 16)
- {
- stride = stride * (int) sizeof (uint32_t) / 2;
- byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
- byte_width = 2 * width;
- stride *= 2;
- xor = (xor & 0xffff) * 0x00010001;
- }
- else
- {
- stride = stride * (int) sizeof (uint32_t) / 4;
- byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
- byte_width = 4 * width;
- stride *= 4;
- }
-
- fill = ((uint64_t)xor << 32) | xor;
- vfill = to_m64 (fill);
-
-#ifdef __GNUC__
- __asm__ (
- "movq %7, %0\n"
- "movq %7, %1\n"
- "movq %7, %2\n"
- "movq %7, %3\n"
- "movq %7, %4\n"
- "movq %7, %5\n"
- "movq %7, %6\n"
- : "=&y" (v1), "=&y" (v2), "=&y" (v3),
- "=&y" (v4), "=&y" (v5), "=&y" (v6), "=y" (v7)
- : "y" (vfill));
-#endif
-
- while (height--)
- {
- int w;
- uint8_t *d = byte_line;
-
- byte_line += stride;
- w = byte_width;
-
- while (w >= 1 && ((unsigned long)d & 1))
- {
- *(uint8_t *)d = (xor & 0xff);
- w--;
- d++;
- }
-
- while (w >= 2 && ((unsigned long)d & 3))
- {
- *(uint16_t *)d = xor;
- w -= 2;
- d += 2;
- }
-
- while (w >= 4 && ((unsigned long)d & 7))
- {
- *(uint32_t *)d = xor;
-
- w -= 4;
- d += 4;
- }
-
- while (w >= 64)
- {
-#ifdef __GNUC__
- __asm__ (
- "movq %1, (%0)\n"
- "movq %2, 8(%0)\n"
- "movq %3, 16(%0)\n"
- "movq %4, 24(%0)\n"
- "movq %5, 32(%0)\n"
- "movq %6, 40(%0)\n"
- "movq %7, 48(%0)\n"
- "movq %8, 56(%0)\n"
- :
- : "r" (d),
- "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
- "y" (v4), "y" (v5), "y" (v6), "y" (v7)
- : "memory");
-#else
- *(__m64*) (d + 0) = vfill;
- *(__m64*) (d + 8) = vfill;
- *(__m64*) (d + 16) = vfill;
- *(__m64*) (d + 24) = vfill;
- *(__m64*) (d + 32) = vfill;
- *(__m64*) (d + 40) = vfill;
- *(__m64*) (d + 48) = vfill;
- *(__m64*) (d + 56) = vfill;
-#endif
- w -= 64;
- d += 64;
- }
-
- while (w >= 4)
- {
- *(uint32_t *)d = xor;
-
- w -= 4;
- d += 4;
- }
- while (w >= 2)
- {
- *(uint16_t *)d = xor;
- w -= 2;
- d += 2;
- }
- while (w >= 1)
- {
- *(uint8_t *)d = (xor & 0xff);
- w--;
- d++;
- }
-
- }
-
- _mm_empty ();
- return TRUE;
-}
-
-static void
-mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t src, srca;
- uint32_t *dst_line, *dst;
- uint8_t *mask_line, *mask;
- int dst_stride, mask_stride;
- int32_t w;
- __m64 vsrc, vsrca;
- uint64_t srcsrc;
-
- CHECKPOINT ();
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- srca = src >> 24;
- if (src == 0)
- {
- pixman_fill_mmx (dst_image->bits.bits, dst_image->bits.rowstride,
- PIXMAN_FORMAT_BPP (dst_image->bits.format),
- dest_x, dest_y, width, height, 0);
- return;
- }
-
- srcsrc = (uint64_t)src << 32 | src;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- mask = mask_line;
- mask_line += mask_stride;
- w = width;
-
- CHECKPOINT ();
-
- while (w && (unsigned long)dst & 7)
- {
- uint64_t m = *mask;
-
- if (m)
- {
- __m64 vdest = in (vsrc, expand_alpha_rev (to_m64 (m)));
-
- *dst = store8888 (vdest);
- }
- else
- {
- *dst = 0;
- }
-
- w--;
- mask++;
- dst++;
- }
-
- CHECKPOINT ();
-
- while (w >= 2)
- {
- uint64_t m0, m1;
- m0 = *mask;
- m1 = *(mask + 1);
-
- if (srca == 0xff && (m0 & m1) == 0xff)
- {
- *(uint64_t *)dst = srcsrc;
- }
- else if (m0 | m1)
- {
- __m64 vdest;
- __m64 dest0, dest1;
-
- vdest = *(__m64 *)dst;
-
- dest0 = in (vsrc, expand_alpha_rev (to_m64 (m0)));
- dest1 = in (vsrc, expand_alpha_rev (to_m64 (m1)));
-
- *(__m64 *)dst = pack8888 (dest0, dest1);
- }
- else
- {
- *(uint64_t *)dst = 0;
- }
-
- mask += 2;
- dst += 2;
- w -= 2;
- }
-
- CHECKPOINT ();
-
- while (w)
- {
- uint64_t m = *mask;
-
- if (m)
- {
- __m64 vdest = load8888 (*dst);
-
- vdest = in (vsrc, expand_alpha_rev (to_m64 (m)));
- *dst = store8888 (vdest);
- }
- else
- {
- *dst = 0;
- }
-
- w--;
- mask++;
- dst++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_n_8_0565 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t src, srca;
- uint16_t *dst_line, *dst;
- uint8_t *mask_line, *mask;
- int dst_stride, mask_stride;
- int32_t w;
- __m64 vsrc, vsrca, tmp;
- uint64_t srcsrcsrcsrc, src16;
-
- CHECKPOINT ();
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- srca = src >> 24;
- if (src == 0)
- return;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- tmp = pack_565 (vsrc, _mm_setzero_si64 (), 0);
- src16 = to_uint64 (tmp);
-
- srcsrcsrcsrc =
- (uint64_t)src16 << 48 | (uint64_t)src16 << 32 |
- (uint64_t)src16 << 16 | (uint64_t)src16;
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- mask = mask_line;
- mask_line += mask_stride;
- w = width;
-
- CHECKPOINT ();
-
- while (w && (unsigned long)dst & 7)
- {
- uint64_t m = *mask;
-
- if (m)
- {
- uint64_t d = *dst;
- __m64 vd = to_m64 (d);
- __m64 vdest = in_over (
- vsrc, vsrca, expand_alpha_rev (to_m64 (m)), expand565 (vd, 0));
-
- vd = pack_565 (vdest, _mm_setzero_si64 (), 0);
- *dst = to_uint64 (vd);
- }
-
- w--;
- mask++;
- dst++;
- }
-
- CHECKPOINT ();
-
- while (w >= 4)
- {
- uint64_t m0, m1, m2, m3;
- m0 = *mask;
- m1 = *(mask + 1);
- m2 = *(mask + 2);
- m3 = *(mask + 3);
-
- if (srca == 0xff && (m0 & m1 & m2 & m3) == 0xff)
- {
- *(uint64_t *)dst = srcsrcsrcsrc;
- }
- else if (m0 | m1 | m2 | m3)
- {
- __m64 vdest;
- __m64 vm0, vm1, vm2, vm3;
-
- vdest = *(__m64 *)dst;
-
- vm0 = to_m64 (m0);
- vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm0),
- expand565 (vdest, 0)), vdest, 0);
- vm1 = to_m64 (m1);
- vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm1),
- expand565 (vdest, 1)), vdest, 1);
- vm2 = to_m64 (m2);
- vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm2),
- expand565 (vdest, 2)), vdest, 2);
- vm3 = to_m64 (m3);
- vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm3),
- expand565 (vdest, 3)), vdest, 3);
-
- *(__m64 *)dst = vdest;
- }
-
- w -= 4;
- mask += 4;
- dst += 4;
- }
-
- CHECKPOINT ();
-
- while (w)
- {
- uint64_t m = *mask;
-
- if (m)
- {
- uint64_t d = *dst;
- __m64 vd = to_m64 (d);
- __m64 vdest = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m)),
- expand565 (vd, 0));
- vd = pack_565 (vdest, _mm_setzero_si64 (), 0);
- *dst = to_uint64 (vd);
- }
-
- w--;
- mask++;
- dst++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_pixbuf_0565 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint16_t *dst_line, *dst;
- uint32_t *src_line, *src;
- int dst_stride, src_stride;
- int32_t w;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
-
-#if 0
- /* FIXME */
- assert (src_image->drawable == mask_image->drawable);
-#endif
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- CHECKPOINT ();
-
- while (w && (unsigned long)dst & 7)
- {
- __m64 vsrc = load8888 (*src);
- uint64_t d = *dst;
- __m64 vdest = expand565 (to_m64 (d), 0);
-
- vdest = pack_565 (over_rev_non_pre (vsrc, vdest), vdest, 0);
-
- *dst = to_uint64 (vdest);
-
- w--;
- dst++;
- src++;
- }
-
- CHECKPOINT ();
-
- while (w >= 4)
- {
- uint32_t s0, s1, s2, s3;
- unsigned char a0, a1, a2, a3;
-
- s0 = *src;
- s1 = *(src + 1);
- s2 = *(src + 2);
- s3 = *(src + 3);
-
- a0 = (s0 >> 24);
- a1 = (s1 >> 24);
- a2 = (s2 >> 24);
- a3 = (s3 >> 24);
-
- if ((a0 & a1 & a2 & a3) == 0xFF)
- {
- __m64 vdest;
- vdest = pack_565 (invert_colors (load8888 (s0)), _mm_setzero_si64 (), 0);
- vdest = pack_565 (invert_colors (load8888 (s1)), vdest, 1);
- vdest = pack_565 (invert_colors (load8888 (s2)), vdest, 2);
- vdest = pack_565 (invert_colors (load8888 (s3)), vdest, 3);
-
- *(__m64 *)dst = vdest;
- }
- else if (s0 | s1 | s2 | s3)
- {
- __m64 vdest = *(__m64 *)dst;
-
- vdest = pack_565 (over_rev_non_pre (load8888 (s0), expand565 (vdest, 0)), vdest, 0);
- vdest = pack_565 (over_rev_non_pre (load8888 (s1), expand565 (vdest, 1)), vdest, 1);
- vdest = pack_565 (over_rev_non_pre (load8888 (s2), expand565 (vdest, 2)), vdest, 2);
- vdest = pack_565 (over_rev_non_pre (load8888 (s3), expand565 (vdest, 3)), vdest, 3);
-
- *(__m64 *)dst = vdest;
- }
-
- w -= 4;
- dst += 4;
- src += 4;
- }
-
- CHECKPOINT ();
-
- while (w)
- {
- __m64 vsrc = load8888 (*src);
- uint64_t d = *dst;
- __m64 vdest = expand565 (to_m64 (d), 0);
-
- vdest = pack_565 (over_rev_non_pre (vsrc, vdest), vdest, 0);
-
- *dst = to_uint64 (vdest);
-
- w--;
- dst++;
- src++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_pixbuf_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t *dst_line, *dst;
- uint32_t *src_line, *src;
- int dst_stride, src_stride;
- int32_t w;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
-
-#if 0
- /* FIXME */
- assert (src_image->drawable == mask_image->drawable);
-#endif
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- while (w && (unsigned long)dst & 7)
- {
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (over_rev_non_pre (s, d));
-
- w--;
- dst++;
- src++;
- }
-
- while (w >= 2)
- {
- uint64_t s0, s1;
- unsigned char a0, a1;
- __m64 d0, d1;
-
- s0 = *src;
- s1 = *(src + 1);
-
- a0 = (s0 >> 24);
- a1 = (s1 >> 24);
-
- if ((a0 & a1) == 0xFF)
- {
- d0 = invert_colors (load8888 (s0));
- d1 = invert_colors (load8888 (s1));
-
- *(__m64 *)dst = pack8888 (d0, d1);
- }
- else if (s0 | s1)
- {
- __m64 vdest = *(__m64 *)dst;
-
- d0 = over_rev_non_pre (load8888 (s0), expand8888 (vdest, 0));
- d1 = over_rev_non_pre (load8888 (s1), expand8888 (vdest, 1));
-
- *(__m64 *)dst = pack8888 (d0, d1);
- }
-
- w -= 2;
- dst += 2;
- src += 2;
- }
-
- while (w)
- {
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (over_rev_non_pre (s, d));
-
- w--;
- dst++;
- src++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_over_n_8888_0565_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t src, srca;
- uint16_t *dst_line;
- uint32_t *mask_line;
- int dst_stride, mask_stride;
- __m64 vsrc, vsrca;
-
- CHECKPOINT ();
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- srca = src >> 24;
- if (src == 0)
- return;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- int twidth = width;
- uint32_t *p = (uint32_t *)mask_line;
- uint16_t *q = (uint16_t *)dst_line;
-
- while (twidth && ((unsigned long)q & 7))
- {
- uint32_t m = *(uint32_t *)p;
-
- if (m)
- {
- uint64_t d = *q;
- __m64 vdest = expand565 (to_m64 (d), 0);
- vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m), vdest), vdest, 0);
- *q = to_uint64 (vdest);
- }
-
- twidth--;
- p++;
- q++;
- }
-
- while (twidth >= 4)
- {
- uint32_t m0, m1, m2, m3;
-
- m0 = *p;
- m1 = *(p + 1);
- m2 = *(p + 2);
- m3 = *(p + 3);
-
- if ((m0 | m1 | m2 | m3))
- {
- __m64 vdest = *(__m64 *)q;
-
- vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m0), expand565 (vdest, 0)), vdest, 0);
- vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m1), expand565 (vdest, 1)), vdest, 1);
- vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m2), expand565 (vdest, 2)), vdest, 2);
- vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m3), expand565 (vdest, 3)), vdest, 3);
-
- *(__m64 *)q = vdest;
- }
- twidth -= 4;
- p += 4;
- q += 4;
- }
-
- while (twidth)
- {
- uint32_t m;
-
- m = *(uint32_t *)p;
- if (m)
- {
- uint64_t d = *q;
- __m64 vdest = expand565 (to_m64 (d), 0);
- vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m), vdest), vdest, 0);
- *q = to_uint64 (vdest);
- }
-
- twidth--;
- p++;
- q++;
- }
-
- mask_line += mask_stride;
- dst_line += dst_stride;
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_in_n_8_8 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint8_t *dst_line, *dst;
- uint8_t *mask_line, *mask;
- int dst_stride, mask_stride;
- int32_t w;
- uint32_t src;
- uint8_t sa;
- __m64 vsrc, vsrca;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- sa = src >> 24;
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- mask = mask_line;
- mask_line += mask_stride;
- w = width;
-
- if ((((unsigned long)dst_image & 3) == 0) &&
- (((unsigned long)src_image & 3) == 0))
- {
- while (w >= 4)
- {
- uint32_t m;
- __m64 vmask;
- __m64 vdest;
-
- m = 0;
-
- vmask = load8888 (*(uint32_t *)mask);
- vdest = load8888 (*(uint32_t *)dst);
-
- *(uint32_t *)dst = store8888 (in (in (vsrca, vmask), vdest));
-
- dst += 4;
- mask += 4;
- w -= 4;
- }
- }
-
- while (w--)
- {
- uint16_t tmp;
- uint8_t a;
- uint32_t m, d;
-
- a = *mask++;
- d = *dst;
-
- m = MUL_UN8 (sa, a, tmp);
- d = MUL_UN8 (m, d, tmp);
-
- *dst++ = d;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_in_8_8 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint8_t *dst_line, *dst;
- uint8_t *src_line, *src;
- int src_stride, dst_stride;
- int32_t w;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- if ((((unsigned long)dst_image & 3) == 0) &&
- (((unsigned long)src_image & 3) == 0))
- {
- while (w >= 4)
- {
- uint32_t *s = (uint32_t *)src;
- uint32_t *d = (uint32_t *)dst;
-
- *d = store8888 (in (load8888 (*s), load8888 (*d)));
-
- w -= 4;
- dst += 4;
- src += 4;
- }
- }
-
- while (w--)
- {
- uint8_t s, d;
- uint16_t tmp;
-
- s = *src;
- d = *dst;
-
- *dst = MUL_UN8 (s, d, tmp);
-
- src++;
- dst++;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_add_n_8_8 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint8_t *dst_line, *dst;
- uint8_t *mask_line, *mask;
- int dst_stride, mask_stride;
- int32_t w;
- uint32_t src;
- uint8_t sa;
- __m64 vsrc, vsrca;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
-
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
-
- sa = src >> 24;
-
- if (src == 0)
- return;
-
- vsrc = load8888 (src);
- vsrca = expand_alpha (vsrc);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- mask = mask_line;
- mask_line += mask_stride;
- w = width;
-
- if ((((unsigned long)mask_image & 3) == 0) &&
- (((unsigned long)dst_image & 3) == 0))
- {
- while (w >= 4)
- {
- __m64 vmask = load8888 (*(uint32_t *)mask);
- __m64 vdest = load8888 (*(uint32_t *)dst);
-
- *(uint32_t *)dst = store8888 (_mm_adds_pu8 (in (vsrca, vmask), vdest));
-
- w -= 4;
- dst += 4;
- mask += 4;
- }
- }
-
- while (w--)
- {
- uint16_t tmp;
- uint16_t a;
- uint32_t m, d;
- uint32_t r;
-
- a = *mask++;
- d = *dst;
-
- m = MUL_UN8 (sa, a, tmp);
- r = ADD_UN8 (m, d, tmp);
-
- *dst++ = r;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_add_8_8 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint8_t *dst_line, *dst;
- uint8_t *src_line, *src;
- int dst_stride, src_stride;
- int32_t w;
- uint8_t s, d;
- uint16_t t;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- while (w && (unsigned long)dst & 7)
- {
- s = *src;
- d = *dst;
- t = d + s;
- s = t | (0 - (t >> 8));
- *dst = s;
-
- dst++;
- src++;
- w--;
- }
-
- while (w >= 8)
- {
- *(__m64*)dst = _mm_adds_pu8 (*(__m64*)src, *(__m64*)dst);
- dst += 8;
- src += 8;
- w -= 8;
- }
-
- while (w)
- {
- s = *src;
- d = *dst;
- t = d + s;
- s = t | (0 - (t >> 8));
- *dst = s;
-
- dst++;
- src++;
- w--;
- }
- }
-
- _mm_empty ();
-}
-
-static void
-mmx_composite_add_8888_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- __m64 dst64;
- uint32_t *dst_line, *dst;
- uint32_t *src_line, *src;
- int dst_stride, src_stride;
- int32_t w;
-
- CHECKPOINT ();
-
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
-
- while (height--)
- {
- dst = dst_line;
- dst_line += dst_stride;
- src = src_line;
- src_line += src_stride;
- w = width;
-
- while (w && (unsigned long)dst & 7)
- {
- *dst = _mm_cvtsi64_si32 (_mm_adds_pu8 (_mm_cvtsi32_si64 (*src),
- _mm_cvtsi32_si64 (*dst)));
- dst++;
- src++;
- w--;
- }
-
- while (w >= 2)
- {
- dst64 = _mm_adds_pu8 (*(__m64*)src, *(__m64*)dst);
- *(uint64_t*)dst = to_uint64 (dst64);
- dst += 2;
- src += 2;
- w -= 2;
- }
-
- if (w)
- {
- *dst = _mm_cvtsi64_si32 (_mm_adds_pu8 (_mm_cvtsi32_si64 (*src),
- _mm_cvtsi32_si64 (*dst)));
-
- }
- }
-
- _mm_empty ();
-}
-
-static pixman_bool_t
-pixman_blt_mmx (uint32_t *src_bits,
- uint32_t *dst_bits,
- int src_stride,
- int dst_stride,
- int src_bpp,
- int dst_bpp,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height)
-{
- uint8_t * src_bytes;
- uint8_t * dst_bytes;
- int byte_width;
-
- if (src_bpp != dst_bpp)
- return FALSE;
-
- if (src_bpp == 16)
- {
- src_stride = src_stride * (int) sizeof (uint32_t) / 2;
- dst_stride = dst_stride * (int) sizeof (uint32_t) / 2;
- src_bytes = (uint8_t *)(((uint16_t *)src_bits) + src_stride * (src_y) + (src_x));
- dst_bytes = (uint8_t *)(((uint16_t *)dst_bits) + dst_stride * (dst_y) + (dst_x));
- byte_width = 2 * width;
- src_stride *= 2;
- dst_stride *= 2;
- }
- else if (src_bpp == 32)
- {
- src_stride = src_stride * (int) sizeof (uint32_t) / 4;
- dst_stride = dst_stride * (int) sizeof (uint32_t) / 4;
- src_bytes = (uint8_t *)(((uint32_t *)src_bits) + src_stride * (src_y) + (src_x));
- dst_bytes = (uint8_t *)(((uint32_t *)dst_bits) + dst_stride * (dst_y) + (dst_x));
- byte_width = 4 * width;
- src_stride *= 4;
- dst_stride *= 4;
- }
- else
- {
- return FALSE;
- }
-
- while (height--)
- {
- int w;
- uint8_t *s = src_bytes;
- uint8_t *d = dst_bytes;
- src_bytes += src_stride;
- dst_bytes += dst_stride;
- w = byte_width;
-
- while (w >= 2 && ((unsigned long)d & 3))
- {
- *(uint16_t *)d = *(uint16_t *)s;
- w -= 2;
- s += 2;
- d += 2;
- }
-
- while (w >= 4 && ((unsigned long)d & 7))
- {
- *(uint32_t *)d = *(uint32_t *)s;
-
- w -= 4;
- s += 4;
- d += 4;
- }
-
- while (w >= 64)
- {
-#if defined (__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
- __asm__ (
- "movq (%1), %%mm0\n"
- "movq 8(%1), %%mm1\n"
- "movq 16(%1), %%mm2\n"
- "movq 24(%1), %%mm3\n"
- "movq 32(%1), %%mm4\n"
- "movq 40(%1), %%mm5\n"
- "movq 48(%1), %%mm6\n"
- "movq 56(%1), %%mm7\n"
-
- "movq %%mm0, (%0)\n"
- "movq %%mm1, 8(%0)\n"
- "movq %%mm2, 16(%0)\n"
- "movq %%mm3, 24(%0)\n"
- "movq %%mm4, 32(%0)\n"
- "movq %%mm5, 40(%0)\n"
- "movq %%mm6, 48(%0)\n"
- "movq %%mm7, 56(%0)\n"
- :
- : "r" (d), "r" (s)
- : "memory",
- "%mm0", "%mm1", "%mm2", "%mm3",
- "%mm4", "%mm5", "%mm6", "%mm7");
-#else
- __m64 v0 = *(__m64 *)(s + 0);
- __m64 v1 = *(__m64 *)(s + 8);
- __m64 v2 = *(__m64 *)(s + 16);
- __m64 v3 = *(__m64 *)(s + 24);
- __m64 v4 = *(__m64 *)(s + 32);
- __m64 v5 = *(__m64 *)(s + 40);
- __m64 v6 = *(__m64 *)(s + 48);
- __m64 v7 = *(__m64 *)(s + 56);
- *(__m64 *)(d + 0) = v0;
- *(__m64 *)(d + 8) = v1;
- *(__m64 *)(d + 16) = v2;
- *(__m64 *)(d + 24) = v3;
- *(__m64 *)(d + 32) = v4;
- *(__m64 *)(d + 40) = v5;
- *(__m64 *)(d + 48) = v6;
- *(__m64 *)(d + 56) = v7;
-#endif
-
- w -= 64;
- s += 64;
- d += 64;
- }
- while (w >= 4)
- {
- *(uint32_t *)d = *(uint32_t *)s;
-
- w -= 4;
- s += 4;
- d += 4;
- }
- if (w >= 2)
- {
- *(uint16_t *)d = *(uint16_t *)s;
- w -= 2;
- s += 2;
- d += 2;
- }
- }
-
- _mm_empty ();
-
- return TRUE;
-}
-
-static void
-mmx_composite_copy_area (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- pixman_blt_mmx (src_image->bits.bits,
- dst_image->bits.bits,
- src_image->bits.rowstride,
- dst_image->bits.rowstride,
- PIXMAN_FORMAT_BPP (src_image->bits.format),
- PIXMAN_FORMAT_BPP (dst_image->bits.format),
- src_x, src_y, dest_x, dest_y, width, height);
-}
-
-#if 0
-static void
-mmx_composite_over_x888_8_8888 (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- uint32_t *src, *src_line;
- uint32_t *dst, *dst_line;
- uint8_t *mask, *mask_line;
- int src_stride, mask_stride, dst_stride;
- int32_t w;
-
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
-
- while (height--)
- {
- src = src_line;
- src_line += src_stride;
- dst = dst_line;
- dst_line += dst_stride;
- mask = mask_line;
- mask_line += mask_stride;
-
- w = width;
-
- while (w--)
- {
- uint64_t m = *mask;
-
- if (m)
- {
- __m64 s = load8888 (*src | 0xff000000);
-
- if (m == 0xff)
- {
- *dst = store8888 (s);
- }
- else
- {
- __m64 sa = expand_alpha (s);
- __m64 vm = expand_alpha_rev (to_m64 (m));
- __m64 vdest = in_over (s, sa, vm, load8888 (*dst));
-
- *dst = store8888 (vdest);
- }
- }
-
- mask++;
- dst++;
- src++;
- }
- }
-
- _mm_empty ();
-}
-#endif
-
-static const pixman_fast_path_t mmx_fast_paths[] =
-{
- PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mmx_composite_over_n_8_0565 ),
- PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mmx_composite_over_n_8_0565 ),
- PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, mmx_composite_over_n_8_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, mmx_composite_over_n_8_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, mmx_composite_over_n_8_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, mmx_composite_over_n_8_8888 ),
- PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mmx_composite_over_n_8888_8888_ca ),
- PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mmx_composite_over_n_8888_8888_ca ),
- PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, mmx_composite_over_n_8888_0565_ca ),
- PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mmx_composite_over_n_8888_8888_ca ),
- PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mmx_composite_over_n_8888_8888_ca ),
- PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, mmx_composite_over_n_8888_0565_ca ),
- PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, a8r8g8b8, mmx_composite_over_pixbuf_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, x8r8g8b8, mmx_composite_over_pixbuf_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, r5g6b5, mmx_composite_over_pixbuf_0565 ),
- PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, a8b8g8r8, mmx_composite_over_pixbuf_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, x8b8g8r8, mmx_composite_over_pixbuf_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, b5g6r5, mmx_composite_over_pixbuf_0565 ),
- PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, a8r8g8b8, mmx_composite_over_x888_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, x8r8g8b8, mmx_composite_over_x888_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, a8b8g8r8, mmx_composite_over_x888_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, x8b8g8r8, mmx_composite_over_x888_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mmx_composite_over_8888_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mmx_composite_over_8888_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, mmx_composite_over_8888_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, mmx_composite_over_8888_n_8888 ),
-#if 0
- /* FIXME: This code is commented out since it's apparently
- * not actually faster than the generic code.
- */
- PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, mmx_composite_over_x888_8_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, mmx_composite_over_x888_8_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, x8b8r8g8, a8, x8b8g8r8, mmx_composite_over_x888_8_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, x8b8r8g8, a8, a8r8g8b8, mmx_composite_over_x888_8_8888 ),
-#endif
- PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, mmx_composite_over_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, mmx_composite_over_n_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, mmx_composite_over_n_0565 ),
- PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ),
-
- PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mmx_composite_over_8888_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mmx_composite_over_8888_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, mmx_composite_over_8888_0565 ),
- PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mmx_composite_over_8888_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mmx_composite_over_8888_8888 ),
- PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, mmx_composite_over_8888_0565 ),
-
- PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, mmx_composite_add_8888_8888 ),
- PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, mmx_composite_add_8888_8888 ),
- PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, mmx_composite_add_8_8 ),
- PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, mmx_composite_add_n_8_8 ),
-
- PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, mmx_composite_src_n_8_8888 ),
- PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, mmx_composite_src_n_8_8888 ),
- PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, mmx_composite_src_n_8_8888 ),
- PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, mmx_composite_src_n_8_8888 ),
- PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, mmx_composite_copy_area ),
- PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, mmx_composite_copy_area ),
-
- PIXMAN_STD_FAST_PATH (IN, a8, null, a8, mmx_composite_in_8_8 ),
- PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, mmx_composite_in_n_8_8 ),
-
- { PIXMAN_OP_NONE },
-};
-
-static pixman_bool_t
-mmx_blt (pixman_implementation_t *imp,
- uint32_t * src_bits,
- uint32_t * dst_bits,
- int src_stride,
- int dst_stride,
- int src_bpp,
- int dst_bpp,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height)
-{
- if (!pixman_blt_mmx (
- src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
- src_x, src_y, dst_x, dst_y, width, height))
-
- {
- return _pixman_implementation_blt (
- imp->delegate,
- src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
- src_x, src_y, dst_x, dst_y, width, height);
- }
-
- return TRUE;
-}
-
-static pixman_bool_t
-mmx_fill (pixman_implementation_t *imp,
- uint32_t * bits,
- int stride,
- int bpp,
- int x,
- int y,
- int width,
- int height,
- uint32_t xor)
-{
- if (!pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
- {
- return _pixman_implementation_fill (
- imp->delegate, bits, stride, bpp, x, y, width, height, xor);
- }
-
- return TRUE;
-}
-
-pixman_implementation_t *
-_pixman_implementation_create_mmx (void)
-{
- pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
- pixman_implementation_t *imp = _pixman_implementation_create (general, mmx_fast_paths);
-
- imp->combine_32[PIXMAN_OP_OVER] = mmx_combine_over_u;
- imp->combine_32[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_u;
- imp->combine_32[PIXMAN_OP_IN] = mmx_combine_in_u;
- imp->combine_32[PIXMAN_OP_IN_REVERSE] = mmx_combine_in_reverse_u;
- imp->combine_32[PIXMAN_OP_OUT] = mmx_combine_out_u;
- imp->combine_32[PIXMAN_OP_OUT_REVERSE] = mmx_combine_out_reverse_u;
- imp->combine_32[PIXMAN_OP_ATOP] = mmx_combine_atop_u;
- imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = mmx_combine_atop_reverse_u;
- imp->combine_32[PIXMAN_OP_XOR] = mmx_combine_xor_u;
- imp->combine_32[PIXMAN_OP_ADD] = mmx_combine_add_u;
- imp->combine_32[PIXMAN_OP_SATURATE] = mmx_combine_saturate_u;
-
- imp->combine_32_ca[PIXMAN_OP_SRC] = mmx_combine_src_ca;
- imp->combine_32_ca[PIXMAN_OP_OVER] = mmx_combine_over_ca;
- imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_IN] = mmx_combine_in_ca;
- imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = mmx_combine_in_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_OUT] = mmx_combine_out_ca;
- imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = mmx_combine_out_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_ATOP] = mmx_combine_atop_ca;
- imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = mmx_combine_atop_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_XOR] = mmx_combine_xor_ca;
- imp->combine_32_ca[PIXMAN_OP_ADD] = mmx_combine_add_ca;
-
- imp->blt = mmx_blt;
- imp->fill = mmx_fill;
-
- return imp;
-}
-
-#endif /* USE_MMX */
+/* + * Copyright © 2004, 2005 Red Hat, Inc. + * Copyright © 2004 Nicholas Miell + * Copyright © 2005 Trolltech AS + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Søren Sandmann (sandmann@redhat.com) + * Minor Improvements: Nicholas Miell (nmiell@gmail.com) + * MMX code paths for fbcompose.c by Lars Knoll (lars@trolltech.com) + * + * Based on work by Owen Taylor + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef USE_MMX + +#include <mmintrin.h> +#include "pixman-private.h" +#include "pixman-combine32.h" + +#define no_vERBOSE + +#ifdef VERBOSE +#define CHECKPOINT() error_f ("at %s %d\n", __FUNCTION__, __LINE__) +#else +#define CHECKPOINT() +#endif + +/* Notes about writing mmx code + * + * give memory operands as the second operand. If you give it as the + * first, gcc will first load it into a register, then use that + * register + * + * ie. use + * + * _mm_mullo_pi16 (x, mmx_constant); + * + * not + * + * _mm_mullo_pi16 (mmx_constant, x); + * + * Also try to minimize dependencies. i.e. when you need a value, try + * to calculate it from a value that was calculated as early as + * possible. + */ + +/* --------------- MMX primitives ------------------------------------- */ + +#ifdef __GNUC__ +typedef uint64_t mmxdatafield; +#else +typedef __m64 mmxdatafield; +/* If __m64 is defined as a struct or union, define M64_MEMBER to be the + name of the member used to access the data */ +# ifdef _MSC_VER +# define M64_MEMBER m64_u64 +# elif defined(__SUNPRO_C) +# define M64_MEMBER l_ +# endif +#endif + +typedef struct +{ + mmxdatafield mmx_4x00ff; + mmxdatafield mmx_4x0080; + mmxdatafield mmx_565_rgb; + mmxdatafield mmx_565_unpack_multiplier; + mmxdatafield mmx_565_r; + mmxdatafield mmx_565_g; + mmxdatafield mmx_565_b; + mmxdatafield mmx_mask_0; + mmxdatafield mmx_mask_1; + mmxdatafield mmx_mask_2; + mmxdatafield mmx_mask_3; + mmxdatafield mmx_full_alpha; + mmxdatafield mmx_ffff0000ffff0000; + mmxdatafield mmx_0000ffff00000000; + mmxdatafield mmx_000000000000ffff; +} mmx_data_t; + +#if defined(_MSC_VER) +# define MMXDATA_INIT(field, val) { val ## UI64 } +#elif defined(M64_MEMBER) /* __m64 is a struct, not an integral type */ +# define MMXDATA_INIT(field, val) field = { val ## ULL } +#else /* __m64 is an integral type */ +# define MMXDATA_INIT(field, val) field = val ## ULL +#endif + +static const mmx_data_t c = +{ + MMXDATA_INIT (.mmx_4x00ff, 0x00ff00ff00ff00ff), + MMXDATA_INIT (.mmx_4x0080, 0x0080008000800080), + MMXDATA_INIT (.mmx_565_rgb, 0x000001f0003f001f), + MMXDATA_INIT (.mmx_565_unpack_multiplier, 0x0000008404100840), + MMXDATA_INIT (.mmx_565_r, 0x000000f800000000), + MMXDATA_INIT (.mmx_565_g, 0x0000000000fc0000), + MMXDATA_INIT (.mmx_565_b, 0x00000000000000f8), + MMXDATA_INIT (.mmx_mask_0, 0xffffffffffff0000), + MMXDATA_INIT (.mmx_mask_1, 0xffffffff0000ffff), + MMXDATA_INIT (.mmx_mask_2, 0xffff0000ffffffff), + MMXDATA_INIT (.mmx_mask_3, 0x0000ffffffffffff), + MMXDATA_INIT (.mmx_full_alpha, 0x00ff000000000000), + MMXDATA_INIT (.mmx_ffff0000ffff0000, 0xffff0000ffff0000), + MMXDATA_INIT (.mmx_0000ffff00000000, 0x0000ffff00000000), + MMXDATA_INIT (.mmx_000000000000ffff, 0x000000000000ffff), +}; + +#ifdef __GNUC__ +# ifdef __ICC +# define MC(x) to_m64 (c.mmx_ ## x) +# else +# define MC(x) ((__m64)c.mmx_ ## x) +# endif +#else +# define MC(x) c.mmx_ ## x +#endif + +static force_inline __m64 +to_m64 (uint64_t x) +{ +#ifdef __ICC + return _mm_cvtsi64_m64 (x); +#elif defined M64_MEMBER /* __m64 is a struct, not an integral type */ + __m64 res; + + res.M64_MEMBER = x; + return res; +#else /* __m64 is an integral type */ + return (__m64)x; +#endif +} + +static force_inline uint64_t +to_uint64 (__m64 x) +{ +#ifdef __ICC + return _mm_cvtm64_si64 (x); +#elif defined M64_MEMBER /* __m64 is a struct, not an integral type */ + uint64_t res = x.M64_MEMBER; + return res; +#else /* __m64 is an integral type */ + return (uint64_t)x; +#endif +} + +static force_inline __m64 +shift (__m64 v, + int s) +{ + if (s > 0) + return _mm_slli_si64 (v, s); + else if (s < 0) + return _mm_srli_si64 (v, -s); + else + return v; +} + +static force_inline __m64 +negate (__m64 mask) +{ + return _mm_xor_si64 (mask, MC (4x00ff)); +} + +static force_inline __m64 +pix_multiply (__m64 a, __m64 b) +{ + __m64 res; + + res = _mm_mullo_pi16 (a, b); + res = _mm_adds_pu16 (res, MC (4x0080)); + res = _mm_adds_pu16 (res, _mm_srli_pi16 (res, 8)); + res = _mm_srli_pi16 (res, 8); + + return res; +} + +static force_inline __m64 +pix_add (__m64 a, __m64 b) +{ + return _mm_adds_pu8 (a, b); +} + +static force_inline __m64 +expand_alpha (__m64 pixel) +{ + __m64 t1, t2; + + t1 = shift (pixel, -48); + t2 = shift (t1, 16); + t1 = _mm_or_si64 (t1, t2); + t2 = shift (t1, 32); + t1 = _mm_or_si64 (t1, t2); + + return t1; +} + +static force_inline __m64 +expand_alpha_rev (__m64 pixel) +{ + __m64 t1, t2; + + /* move alpha to low 16 bits and zero the rest */ + t1 = shift (pixel, 48); + t1 = shift (t1, -48); + + t2 = shift (t1, 16); + t1 = _mm_or_si64 (t1, t2); + t2 = shift (t1, 32); + t1 = _mm_or_si64 (t1, t2); + + return t1; +} + +static force_inline __m64 +invert_colors (__m64 pixel) +{ + __m64 x, y, z; + + x = y = z = pixel; + + x = _mm_and_si64 (x, MC (ffff0000ffff0000)); + y = _mm_and_si64 (y, MC (000000000000ffff)); + z = _mm_and_si64 (z, MC (0000ffff00000000)); + + y = shift (y, 32); + z = shift (z, -32); + + x = _mm_or_si64 (x, y); + x = _mm_or_si64 (x, z); + + return x; +} + +static force_inline __m64 +over (__m64 src, + __m64 srca, + __m64 dest) +{ + return _mm_adds_pu8 (src, pix_multiply (dest, negate (srca))); +} + +static force_inline __m64 +over_rev_non_pre (__m64 src, __m64 dest) +{ + __m64 srca = expand_alpha (src); + __m64 srcfaaa = _mm_or_si64 (srca, MC (full_alpha)); + + return over (pix_multiply (invert_colors (src), srcfaaa), srca, dest); +} + +static force_inline __m64 +in (__m64 src, __m64 mask) +{ + return pix_multiply (src, mask); +} + +static force_inline __m64 +in_over_full_src_alpha (__m64 src, __m64 mask, __m64 dest) +{ + src = _mm_or_si64 (src, MC (full_alpha)); + + return over (in (src, mask), mask, dest); +} + +#ifndef _MSC_VER +static force_inline __m64 +in_over (__m64 src, __m64 srca, __m64 mask, __m64 dest) +{ + return over (in (src, mask), pix_multiply (srca, mask), dest); +} + +#else + +#define in_over(src, srca, mask, dest) \ + over (in (src, mask), pix_multiply (srca, mask), dest) + +#endif + +static force_inline __m64 +load8888 (uint32_t v) +{ + return _mm_unpacklo_pi8 (_mm_cvtsi32_si64 (v), _mm_setzero_si64 ()); +} + +static force_inline __m64 +pack8888 (__m64 lo, __m64 hi) +{ + return _mm_packs_pu16 (lo, hi); +} + +static force_inline uint32_t +store8888 (__m64 v) +{ + return _mm_cvtsi64_si32 (pack8888 (v, _mm_setzero_si64 ())); +} + +/* Expand 16 bits positioned at @pos (0-3) of a mmx register into + * + * 00RR00GG00BB + * + * --- Expanding 565 in the low word --- + * + * m = (m << (32 - 3)) | (m << (16 - 5)) | m; + * m = m & (01f0003f001f); + * m = m * (008404100840); + * m = m >> 8; + * + * Note the trick here - the top word is shifted by another nibble to + * avoid it bumping into the middle word + */ +static force_inline __m64 +expand565 (__m64 pixel, int pos) +{ + __m64 p = pixel; + __m64 t1, t2; + + /* move pixel to low 16 bit and zero the rest */ + p = shift (shift (p, (3 - pos) * 16), -48); + + t1 = shift (p, 36 - 11); + t2 = shift (p, 16 - 5); + + p = _mm_or_si64 (t1, p); + p = _mm_or_si64 (t2, p); + p = _mm_and_si64 (p, MC (565_rgb)); + + pixel = _mm_mullo_pi16 (p, MC (565_unpack_multiplier)); + return _mm_srli_pi16 (pixel, 8); +} + +static force_inline __m64 +expand8888 (__m64 in, int pos) +{ + if (pos == 0) + return _mm_unpacklo_pi8 (in, _mm_setzero_si64 ()); + else + return _mm_unpackhi_pi8 (in, _mm_setzero_si64 ()); +} + +static force_inline __m64 +expandx888 (__m64 in, int pos) +{ + return _mm_or_si64 (expand8888 (in, pos), MC (full_alpha)); +} + +static force_inline __m64 +pack_565 (__m64 pixel, __m64 target, int pos) +{ + __m64 p = pixel; + __m64 t = target; + __m64 r, g, b; + + r = _mm_and_si64 (p, MC (565_r)); + g = _mm_and_si64 (p, MC (565_g)); + b = _mm_and_si64 (p, MC (565_b)); + + r = shift (r, -(32 - 8) + pos * 16); + g = shift (g, -(16 - 3) + pos * 16); + b = shift (b, -(0 + 3) + pos * 16); + + if (pos == 0) + t = _mm_and_si64 (t, MC (mask_0)); + else if (pos == 1) + t = _mm_and_si64 (t, MC (mask_1)); + else if (pos == 2) + t = _mm_and_si64 (t, MC (mask_2)); + else if (pos == 3) + t = _mm_and_si64 (t, MC (mask_3)); + + p = _mm_or_si64 (r, t); + p = _mm_or_si64 (g, p); + + return _mm_or_si64 (b, p); +} + +#ifndef _MSC_VER + +static force_inline __m64 +pix_add_mul (__m64 x, __m64 a, __m64 y, __m64 b) +{ + x = pix_multiply (x, a); + y = pix_multiply (y, b); + + return pix_add (x, y); +} + +#else + +#define pix_add_mul(x, a, y, b) \ + ( x = pix_multiply (x, a), \ + y = pix_multiply (y, a), \ + pix_add (x, y) ) + +#endif + +/* --------------- MMX code patch for fbcompose.c --------------------- */ + +static force_inline uint32_t +combine (const uint32_t *src, const uint32_t *mask) +{ + uint32_t ssrc = *src; + + if (mask) + { + __m64 m = load8888 (*mask); + __m64 s = load8888 (ssrc); + + m = expand_alpha (m); + s = pix_multiply (s, m); + + ssrc = store8888 (s); + } + + return ssrc; +} + +static void +mmx_combine_over_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + uint32_t ssrc = combine (src, mask); + uint32_t a = ssrc >> 24; + + if (a == 0xff) + { + *dest = ssrc; + } + else if (ssrc) + { + __m64 s, sa; + s = load8888 (ssrc); + sa = expand_alpha (s); + *dest = store8888 (over (s, sa, load8888 (*dest))); + } + + ++dest; + ++src; + if (mask) + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_over_reverse_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 d, da; + uint32_t s = combine (src, mask); + + d = load8888 (*dest); + da = expand_alpha (d); + *dest = store8888 (over (d, da, load8888 (s))); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_in_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 x, a; + + x = load8888 (combine (src, mask)); + a = load8888 (*dest); + a = expand_alpha (a); + x = pix_multiply (x, a); + + *dest = store8888 (x); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_in_reverse_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 x, a; + + x = load8888 (*dest); + a = load8888 (combine (src, mask)); + a = expand_alpha (a); + x = pix_multiply (x, a); + *dest = store8888 (x); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_out_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 x, a; + + x = load8888 (combine (src, mask)); + a = load8888 (*dest); + a = expand_alpha (a); + a = negate (a); + x = pix_multiply (x, a); + *dest = store8888 (x); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_out_reverse_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 x, a; + + x = load8888 (*dest); + a = load8888 (combine (src, mask)); + a = expand_alpha (a); + a = negate (a); + x = pix_multiply (x, a); + + *dest = store8888 (x); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_atop_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 s, da, d, sia; + + s = load8888 (combine (src, mask)); + d = load8888 (*dest); + sia = expand_alpha (s); + sia = negate (sia); + da = expand_alpha (d); + s = pix_add_mul (s, da, d, sia); + *dest = store8888 (s); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_atop_reverse_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end; + + end = dest + width; + + while (dest < end) + { + __m64 s, dia, d, sa; + + s = load8888 (combine (src, mask)); + d = load8888 (*dest); + sa = expand_alpha (s); + dia = expand_alpha (d); + dia = negate (dia); + s = pix_add_mul (s, dia, d, sa); + *dest = store8888 (s); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_xor_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 s, dia, d, sia; + + s = load8888 (combine (src, mask)); + d = load8888 (*dest); + sia = expand_alpha (s); + dia = expand_alpha (d); + sia = negate (sia); + dia = negate (dia); + s = pix_add_mul (s, dia, d, sia); + *dest = store8888 (s); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_add_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + __m64 s, d; + + s = load8888 (combine (src, mask)); + d = load8888 (*dest); + s = pix_add (s, d); + *dest = store8888 (s); + + ++dest; + ++src; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_saturate_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = dest + width; + + while (dest < end) + { + uint32_t s = combine (src, mask); + uint32_t d = *dest; + __m64 ms = load8888 (s); + __m64 md = load8888 (d); + uint32_t sa = s >> 24; + uint32_t da = ~d >> 24; + + if (sa > da) + { + __m64 msa = load8888 (DIV_UN8 (da, sa) << 24); + msa = expand_alpha (msa); + ms = pix_multiply (ms, msa); + } + + md = pix_add (md, ms); + *dest = store8888 (md); + + ++src; + ++dest; + if (mask) + mask++; + } + _mm_empty (); +} + +static void +mmx_combine_src_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + + s = pix_multiply (s, a); + *dest = store8888 (s); + + ++src; + ++mask; + ++dest; + } + _mm_empty (); +} + +static void +mmx_combine_over_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 sa = expand_alpha (s); + + *dest = store8888 (in_over (s, sa, a, d)); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_over_reverse_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 da = expand_alpha (d); + + *dest = store8888 (over (d, da, in (s, a))); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_in_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 da = expand_alpha (d); + + s = pix_multiply (s, a); + s = pix_multiply (s, da); + *dest = store8888 (s); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_in_reverse_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 sa = expand_alpha (s); + + a = pix_multiply (a, sa); + d = pix_multiply (d, a); + *dest = store8888 (d); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_out_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 da = expand_alpha (d); + + da = negate (da); + s = pix_multiply (s, a); + s = pix_multiply (s, da); + *dest = store8888 (s); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_out_reverse_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 sa = expand_alpha (s); + + a = pix_multiply (a, sa); + a = negate (a); + d = pix_multiply (d, a); + *dest = store8888 (d); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_atop_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 da = expand_alpha (d); + __m64 sa = expand_alpha (s); + + s = pix_multiply (s, a); + a = pix_multiply (a, sa); + a = negate (a); + d = pix_add_mul (d, a, s, da); + *dest = store8888 (d); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_atop_reverse_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 da = expand_alpha (d); + __m64 sa = expand_alpha (s); + + s = pix_multiply (s, a); + a = pix_multiply (a, sa); + da = negate (da); + d = pix_add_mul (d, a, s, da); + *dest = store8888 (d); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_xor_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + __m64 da = expand_alpha (d); + __m64 sa = expand_alpha (s); + + s = pix_multiply (s, a); + a = pix_multiply (a, sa); + da = negate (da); + a = negate (a); + d = pix_add_mul (d, a, s, da); + *dest = store8888 (d); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +static void +mmx_combine_add_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + const uint32_t *end = src + width; + + while (src < end) + { + __m64 a = load8888 (*mask); + __m64 s = load8888 (*src); + __m64 d = load8888 (*dest); + + s = pix_multiply (s, a); + d = pix_add (s, d); + *dest = store8888 (d); + + ++src; + ++dest; + ++mask; + } + _mm_empty (); +} + +/* ------------- MMX code paths called from fbpict.c -------------------- */ + +static void +mmx_composite_over_n_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src; + uint32_t *dst_line, *dst; + int32_t w; + int dst_stride; + __m64 vsrc, vsrca; + + CHECKPOINT (); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + if (src == 0) + return; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + w = width; + + CHECKPOINT (); + + while (w && (unsigned long)dst & 7) + { + *dst = store8888 (over (vsrc, vsrca, load8888 (*dst))); + + w--; + dst++; + } + + while (w >= 2) + { + __m64 vdest; + __m64 dest0, dest1; + + vdest = *(__m64 *)dst; + + dest0 = over (vsrc, vsrca, expand8888 (vdest, 0)); + dest1 = over (vsrc, vsrca, expand8888 (vdest, 1)); + + *(__m64 *)dst = pack8888 (dest0, dest1); + + dst += 2; + w -= 2; + } + + CHECKPOINT (); + + while (w) + { + *dst = store8888 (over (vsrc, vsrca, load8888 (*dst))); + + w--; + dst++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_n_0565 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src; + uint16_t *dst_line, *dst; + int32_t w; + int dst_stride; + __m64 vsrc, vsrca; + + CHECKPOINT (); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + if (src == 0) + return; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + w = width; + + CHECKPOINT (); + + while (w && (unsigned long)dst & 7) + { + uint64_t d = *dst; + __m64 vdest = expand565 (to_m64 (d), 0); + + vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0); + *dst = to_uint64 (vdest); + + w--; + dst++; + } + + while (w >= 4) + { + __m64 vdest; + + vdest = *(__m64 *)dst; + + vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 0)), vdest, 0); + vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 1)), vdest, 1); + vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 2)), vdest, 2); + vdest = pack_565 (over (vsrc, vsrca, expand565 (vdest, 3)), vdest, 3); + + *(__m64 *)dst = vdest; + + dst += 4; + w -= 4; + } + + CHECKPOINT (); + + while (w) + { + uint64_t d = *dst; + __m64 vdest = expand565 (to_m64 (d), 0); + + vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0); + *dst = to_uint64 (vdest); + + w--; + dst++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_n_8888_8888_ca (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src, srca; + uint32_t *dst_line; + uint32_t *mask_line; + int dst_stride, mask_stride; + __m64 vsrc, vsrca; + + CHECKPOINT (); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + srca = src >> 24; + if (src == 0) + return; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + int twidth = width; + uint32_t *p = (uint32_t *)mask_line; + uint32_t *q = (uint32_t *)dst_line; + + while (twidth && (unsigned long)q & 7) + { + uint32_t m = *(uint32_t *)p; + + if (m) + { + __m64 vdest = load8888 (*q); + vdest = in_over (vsrc, vsrca, load8888 (m), vdest); + *q = store8888 (vdest); + } + + twidth--; + p++; + q++; + } + + while (twidth >= 2) + { + uint32_t m0, m1; + m0 = *p; + m1 = *(p + 1); + + if (m0 | m1) + { + __m64 dest0, dest1; + __m64 vdest = *(__m64 *)q; + + dest0 = in_over (vsrc, vsrca, load8888 (m0), + expand8888 (vdest, 0)); + dest1 = in_over (vsrc, vsrca, load8888 (m1), + expand8888 (vdest, 1)); + + *(__m64 *)q = pack8888 (dest0, dest1); + } + + p += 2; + q += 2; + twidth -= 2; + } + + while (twidth) + { + uint32_t m = *(uint32_t *)p; + + if (m) + { + __m64 vdest = load8888 (*q); + vdest = in_over (vsrc, vsrca, load8888 (m), vdest); + *q = store8888 (vdest); + } + + twidth--; + p++; + q++; + } + + dst_line += dst_stride; + mask_line += mask_stride; + } + + _mm_empty (); +} + +static void +mmx_composite_over_8888_n_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t *dst_line, *dst; + uint32_t *src_line, *src; + uint32_t mask; + __m64 vmask; + int dst_stride, src_stride; + int32_t w; + __m64 srca; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + + mask = _pixman_image_get_solid (imp, mask_image, dst_image->bits.format); + mask &= 0xff000000; + mask = mask | mask >> 8 | mask >> 16 | mask >> 24; + vmask = load8888 (mask); + srca = MC (4x00ff); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + while (w && (unsigned long)dst & 7) + { + __m64 s = load8888 (*src); + __m64 d = load8888 (*dst); + + *dst = store8888 (in_over (s, expand_alpha (s), vmask, d)); + + w--; + dst++; + src++; + } + + while (w >= 2) + { + __m64 vs = *(__m64 *)src; + __m64 vd = *(__m64 *)dst; + __m64 vsrc0 = expand8888 (vs, 0); + __m64 vsrc1 = expand8888 (vs, 1); + + *(__m64 *)dst = pack8888 ( + in_over (vsrc0, expand_alpha (vsrc0), vmask, expand8888 (vd, 0)), + in_over (vsrc1, expand_alpha (vsrc1), vmask, expand8888 (vd, 1))); + + w -= 2; + dst += 2; + src += 2; + } + + while (w) + { + __m64 s = load8888 (*src); + __m64 d = load8888 (*dst); + + *dst = store8888 (in_over (s, expand_alpha (s), vmask, d)); + + w--; + dst++; + src++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_x888_n_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t *dst_line, *dst; + uint32_t *src_line, *src; + uint32_t mask; + __m64 vmask; + int dst_stride, src_stride; + int32_t w; + __m64 srca; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + mask = _pixman_image_get_solid (imp, mask_image, dst_image->bits.format); + + mask &= 0xff000000; + mask = mask | mask >> 8 | mask >> 16 | mask >> 24; + vmask = load8888 (mask); + srca = MC (4x00ff); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + while (w && (unsigned long)dst & 7) + { + __m64 s = load8888 (*src | 0xff000000); + __m64 d = load8888 (*dst); + + *dst = store8888 (in_over (s, srca, vmask, d)); + + w--; + dst++; + src++; + } + + while (w >= 16) + { + __m64 vd0 = *(__m64 *)(dst + 0); + __m64 vd1 = *(__m64 *)(dst + 2); + __m64 vd2 = *(__m64 *)(dst + 4); + __m64 vd3 = *(__m64 *)(dst + 6); + __m64 vd4 = *(__m64 *)(dst + 8); + __m64 vd5 = *(__m64 *)(dst + 10); + __m64 vd6 = *(__m64 *)(dst + 12); + __m64 vd7 = *(__m64 *)(dst + 14); + + __m64 vs0 = *(__m64 *)(src + 0); + __m64 vs1 = *(__m64 *)(src + 2); + __m64 vs2 = *(__m64 *)(src + 4); + __m64 vs3 = *(__m64 *)(src + 6); + __m64 vs4 = *(__m64 *)(src + 8); + __m64 vs5 = *(__m64 *)(src + 10); + __m64 vs6 = *(__m64 *)(src + 12); + __m64 vs7 = *(__m64 *)(src + 14); + + vd0 = pack8888 ( + in_over (expandx888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)), + in_over (expandx888 (vs0, 1), srca, vmask, expand8888 (vd0, 1))); + + vd1 = pack8888 ( + in_over (expandx888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)), + in_over (expandx888 (vs1, 1), srca, vmask, expand8888 (vd1, 1))); + + vd2 = pack8888 ( + in_over (expandx888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)), + in_over (expandx888 (vs2, 1), srca, vmask, expand8888 (vd2, 1))); + + vd3 = pack8888 ( + in_over (expandx888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)), + in_over (expandx888 (vs3, 1), srca, vmask, expand8888 (vd3, 1))); + + vd4 = pack8888 ( + in_over (expandx888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)), + in_over (expandx888 (vs4, 1), srca, vmask, expand8888 (vd4, 1))); + + vd5 = pack8888 ( + in_over (expandx888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)), + in_over (expandx888 (vs5, 1), srca, vmask, expand8888 (vd5, 1))); + + vd6 = pack8888 ( + in_over (expandx888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)), + in_over (expandx888 (vs6, 1), srca, vmask, expand8888 (vd6, 1))); + + vd7 = pack8888 ( + in_over (expandx888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)), + in_over (expandx888 (vs7, 1), srca, vmask, expand8888 (vd7, 1))); + + *(__m64 *)(dst + 0) = vd0; + *(__m64 *)(dst + 2) = vd1; + *(__m64 *)(dst + 4) = vd2; + *(__m64 *)(dst + 6) = vd3; + *(__m64 *)(dst + 8) = vd4; + *(__m64 *)(dst + 10) = vd5; + *(__m64 *)(dst + 12) = vd6; + *(__m64 *)(dst + 14) = vd7; + + w -= 16; + dst += 16; + src += 16; + } + + while (w) + { + __m64 s = load8888 (*src | 0xff000000); + __m64 d = load8888 (*dst); + + *dst = store8888 (in_over (s, srca, vmask, d)); + + w--; + dst++; + src++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_8888_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t *dst_line, *dst; + uint32_t *src_line, *src; + uint32_t s; + int dst_stride, src_stride; + uint8_t a; + int32_t w; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + while (w--) + { + s = *src++; + a = s >> 24; + + if (a == 0xff) + { + *dst = s; + } + else if (s) + { + __m64 ms, sa; + ms = load8888 (s); + sa = expand_alpha (ms); + *dst = store8888 (over (ms, sa, load8888 (*dst))); + } + + dst++; + } + } + _mm_empty (); +} + +static void +mmx_composite_over_8888_0565 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint16_t *dst_line, *dst; + uint32_t *src_line, *src; + int dst_stride, src_stride; + int32_t w; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + +#if 0 + /* FIXME */ + assert (src_image->drawable == mask_image->drawable); +#endif + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + CHECKPOINT (); + + while (w && (unsigned long)dst & 7) + { + __m64 vsrc = load8888 (*src); + uint64_t d = *dst; + __m64 vdest = expand565 (to_m64 (d), 0); + + vdest = pack_565 ( + over (vsrc, expand_alpha (vsrc), vdest), vdest, 0); + + *dst = to_uint64 (vdest); + + w--; + dst++; + src++; + } + + CHECKPOINT (); + + while (w >= 4) + { + __m64 vsrc0, vsrc1, vsrc2, vsrc3; + __m64 vdest; + + vsrc0 = load8888 (*(src + 0)); + vsrc1 = load8888 (*(src + 1)); + vsrc2 = load8888 (*(src + 2)); + vsrc3 = load8888 (*(src + 3)); + + vdest = *(__m64 *)dst; + + vdest = pack_565 (over (vsrc0, expand_alpha (vsrc0), expand565 (vdest, 0)), vdest, 0); + vdest = pack_565 (over (vsrc1, expand_alpha (vsrc1), expand565 (vdest, 1)), vdest, 1); + vdest = pack_565 (over (vsrc2, expand_alpha (vsrc2), expand565 (vdest, 2)), vdest, 2); + vdest = pack_565 (over (vsrc3, expand_alpha (vsrc3), expand565 (vdest, 3)), vdest, 3); + + *(__m64 *)dst = vdest; + + w -= 4; + dst += 4; + src += 4; + } + + CHECKPOINT (); + + while (w) + { + __m64 vsrc = load8888 (*src); + uint64_t d = *dst; + __m64 vdest = expand565 (to_m64 (d), 0); + + vdest = pack_565 (over (vsrc, expand_alpha (vsrc), vdest), vdest, 0); + + *dst = to_uint64 (vdest); + + w--; + dst++; + src++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_n_8_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src, srca; + uint32_t *dst_line, *dst; + uint8_t *mask_line, *mask; + int dst_stride, mask_stride; + int32_t w; + __m64 vsrc, vsrca; + uint64_t srcsrc; + + CHECKPOINT (); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + srca = src >> 24; + if (src == 0) + return; + + srcsrc = (uint64_t)src << 32 | src; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + w = width; + + CHECKPOINT (); + + while (w && (unsigned long)dst & 7) + { + uint64_t m = *mask; + + if (m) + { + __m64 vdest = in_over (vsrc, vsrca, + expand_alpha_rev (to_m64 (m)), + load8888 (*dst)); + + *dst = store8888 (vdest); + } + + w--; + mask++; + dst++; + } + + CHECKPOINT (); + + while (w >= 2) + { + uint64_t m0, m1; + + m0 = *mask; + m1 = *(mask + 1); + + if (srca == 0xff && (m0 & m1) == 0xff) + { + *(uint64_t *)dst = srcsrc; + } + else if (m0 | m1) + { + __m64 vdest; + __m64 dest0, dest1; + + vdest = *(__m64 *)dst; + + dest0 = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m0)), + expand8888 (vdest, 0)); + dest1 = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m1)), + expand8888 (vdest, 1)); + + *(__m64 *)dst = pack8888 (dest0, dest1); + } + + mask += 2; + dst += 2; + w -= 2; + } + + CHECKPOINT (); + + while (w) + { + uint64_t m = *mask; + + if (m) + { + __m64 vdest = load8888 (*dst); + + vdest = in_over ( + vsrc, vsrca, expand_alpha_rev (to_m64 (m)), vdest); + *dst = store8888 (vdest); + } + + w--; + mask++; + dst++; + } + } + + _mm_empty (); +} + +pixman_bool_t +pixman_fill_mmx (uint32_t *bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) +{ + uint64_t fill; + __m64 vfill; + uint32_t byte_width; + uint8_t *byte_line; + +#ifdef __GNUC__ + __m64 v1, v2, v3, v4, v5, v6, v7; +#endif + + if (bpp != 16 && bpp != 32 && bpp != 8) + return FALSE; + + if (bpp == 8) + { + stride = stride * (int) sizeof (uint32_t) / 1; + byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x); + byte_width = width; + stride *= 1; + xor = (xor & 0xff) * 0x01010101; + } + else if (bpp == 16) + { + stride = stride * (int) sizeof (uint32_t) / 2; + byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x); + byte_width = 2 * width; + stride *= 2; + xor = (xor & 0xffff) * 0x00010001; + } + else + { + stride = stride * (int) sizeof (uint32_t) / 4; + byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x); + byte_width = 4 * width; + stride *= 4; + } + + fill = ((uint64_t)xor << 32) | xor; + vfill = to_m64 (fill); + +#ifdef __GNUC__ + __asm__ ( + "movq %7, %0\n" + "movq %7, %1\n" + "movq %7, %2\n" + "movq %7, %3\n" + "movq %7, %4\n" + "movq %7, %5\n" + "movq %7, %6\n" + : "=&y" (v1), "=&y" (v2), "=&y" (v3), + "=&y" (v4), "=&y" (v5), "=&y" (v6), "=y" (v7) + : "y" (vfill)); +#endif + + while (height--) + { + int w; + uint8_t *d = byte_line; + + byte_line += stride; + w = byte_width; + + while (w >= 1 && ((unsigned long)d & 1)) + { + *(uint8_t *)d = (xor & 0xff); + w--; + d++; + } + + while (w >= 2 && ((unsigned long)d & 3)) + { + *(uint16_t *)d = xor; + w -= 2; + d += 2; + } + + while (w >= 4 && ((unsigned long)d & 7)) + { + *(uint32_t *)d = xor; + + w -= 4; + d += 4; + } + + while (w >= 64) + { +#ifdef __GNUC__ + __asm__ ( + "movq %1, (%0)\n" + "movq %2, 8(%0)\n" + "movq %3, 16(%0)\n" + "movq %4, 24(%0)\n" + "movq %5, 32(%0)\n" + "movq %6, 40(%0)\n" + "movq %7, 48(%0)\n" + "movq %8, 56(%0)\n" + : + : "r" (d), + "y" (vfill), "y" (v1), "y" (v2), "y" (v3), + "y" (v4), "y" (v5), "y" (v6), "y" (v7) + : "memory"); +#else + *(__m64*) (d + 0) = vfill; + *(__m64*) (d + 8) = vfill; + *(__m64*) (d + 16) = vfill; + *(__m64*) (d + 24) = vfill; + *(__m64*) (d + 32) = vfill; + *(__m64*) (d + 40) = vfill; + *(__m64*) (d + 48) = vfill; + *(__m64*) (d + 56) = vfill; +#endif + w -= 64; + d += 64; + } + + while (w >= 4) + { + *(uint32_t *)d = xor; + + w -= 4; + d += 4; + } + while (w >= 2) + { + *(uint16_t *)d = xor; + w -= 2; + d += 2; + } + while (w >= 1) + { + *(uint8_t *)d = (xor & 0xff); + w--; + d++; + } + + } + + _mm_empty (); + return TRUE; +} + +static void +mmx_composite_src_n_8_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src, srca; + uint32_t *dst_line, *dst; + uint8_t *mask_line, *mask; + int dst_stride, mask_stride; + int32_t w; + __m64 vsrc, vsrca; + uint64_t srcsrc; + + CHECKPOINT (); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + srca = src >> 24; + if (src == 0) + { + pixman_fill_mmx (dst_image->bits.bits, dst_image->bits.rowstride, + PIXMAN_FORMAT_BPP (dst_image->bits.format), + dest_x, dest_y, width, height, 0); + return; + } + + srcsrc = (uint64_t)src << 32 | src; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + w = width; + + CHECKPOINT (); + + while (w && (unsigned long)dst & 7) + { + uint64_t m = *mask; + + if (m) + { + __m64 vdest = in (vsrc, expand_alpha_rev (to_m64 (m))); + + *dst = store8888 (vdest); + } + else + { + *dst = 0; + } + + w--; + mask++; + dst++; + } + + CHECKPOINT (); + + while (w >= 2) + { + uint64_t m0, m1; + m0 = *mask; + m1 = *(mask + 1); + + if (srca == 0xff && (m0 & m1) == 0xff) + { + *(uint64_t *)dst = srcsrc; + } + else if (m0 | m1) + { + __m64 vdest; + __m64 dest0, dest1; + + vdest = *(__m64 *)dst; + + dest0 = in (vsrc, expand_alpha_rev (to_m64 (m0))); + dest1 = in (vsrc, expand_alpha_rev (to_m64 (m1))); + + *(__m64 *)dst = pack8888 (dest0, dest1); + } + else + { + *(uint64_t *)dst = 0; + } + + mask += 2; + dst += 2; + w -= 2; + } + + CHECKPOINT (); + + while (w) + { + uint64_t m = *mask; + + if (m) + { + __m64 vdest = load8888 (*dst); + + vdest = in (vsrc, expand_alpha_rev (to_m64 (m))); + *dst = store8888 (vdest); + } + else + { + *dst = 0; + } + + w--; + mask++; + dst++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_n_8_0565 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src, srca; + uint16_t *dst_line, *dst; + uint8_t *mask_line, *mask; + int dst_stride, mask_stride; + int32_t w; + __m64 vsrc, vsrca, tmp; + uint64_t srcsrcsrcsrc, src16; + + CHECKPOINT (); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + srca = src >> 24; + if (src == 0) + return; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + tmp = pack_565 (vsrc, _mm_setzero_si64 (), 0); + src16 = to_uint64 (tmp); + + srcsrcsrcsrc = + (uint64_t)src16 << 48 | (uint64_t)src16 << 32 | + (uint64_t)src16 << 16 | (uint64_t)src16; + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + w = width; + + CHECKPOINT (); + + while (w && (unsigned long)dst & 7) + { + uint64_t m = *mask; + + if (m) + { + uint64_t d = *dst; + __m64 vd = to_m64 (d); + __m64 vdest = in_over ( + vsrc, vsrca, expand_alpha_rev (to_m64 (m)), expand565 (vd, 0)); + + vd = pack_565 (vdest, _mm_setzero_si64 (), 0); + *dst = to_uint64 (vd); + } + + w--; + mask++; + dst++; + } + + CHECKPOINT (); + + while (w >= 4) + { + uint64_t m0, m1, m2, m3; + m0 = *mask; + m1 = *(mask + 1); + m2 = *(mask + 2); + m3 = *(mask + 3); + + if (srca == 0xff && (m0 & m1 & m2 & m3) == 0xff) + { + *(uint64_t *)dst = srcsrcsrcsrc; + } + else if (m0 | m1 | m2 | m3) + { + __m64 vdest; + __m64 vm0, vm1, vm2, vm3; + + vdest = *(__m64 *)dst; + + vm0 = to_m64 (m0); + vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm0), + expand565 (vdest, 0)), vdest, 0); + vm1 = to_m64 (m1); + vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm1), + expand565 (vdest, 1)), vdest, 1); + vm2 = to_m64 (m2); + vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm2), + expand565 (vdest, 2)), vdest, 2); + vm3 = to_m64 (m3); + vdest = pack_565 (in_over (vsrc, vsrca, expand_alpha_rev (vm3), + expand565 (vdest, 3)), vdest, 3); + + *(__m64 *)dst = vdest; + } + + w -= 4; + mask += 4; + dst += 4; + } + + CHECKPOINT (); + + while (w) + { + uint64_t m = *mask; + + if (m) + { + uint64_t d = *dst; + __m64 vd = to_m64 (d); + __m64 vdest = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m)), + expand565 (vd, 0)); + vd = pack_565 (vdest, _mm_setzero_si64 (), 0); + *dst = to_uint64 (vd); + } + + w--; + mask++; + dst++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_pixbuf_0565 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint16_t *dst_line, *dst; + uint32_t *src_line, *src; + int dst_stride, src_stride; + int32_t w; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + +#if 0 + /* FIXME */ + assert (src_image->drawable == mask_image->drawable); +#endif + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + CHECKPOINT (); + + while (w && (unsigned long)dst & 7) + { + __m64 vsrc = load8888 (*src); + uint64_t d = *dst; + __m64 vdest = expand565 (to_m64 (d), 0); + + vdest = pack_565 (over_rev_non_pre (vsrc, vdest), vdest, 0); + + *dst = to_uint64 (vdest); + + w--; + dst++; + src++; + } + + CHECKPOINT (); + + while (w >= 4) + { + uint32_t s0, s1, s2, s3; + unsigned char a0, a1, a2, a3; + + s0 = *src; + s1 = *(src + 1); + s2 = *(src + 2); + s3 = *(src + 3); + + a0 = (s0 >> 24); + a1 = (s1 >> 24); + a2 = (s2 >> 24); + a3 = (s3 >> 24); + + if ((a0 & a1 & a2 & a3) == 0xFF) + { + __m64 vdest; + vdest = pack_565 (invert_colors (load8888 (s0)), _mm_setzero_si64 (), 0); + vdest = pack_565 (invert_colors (load8888 (s1)), vdest, 1); + vdest = pack_565 (invert_colors (load8888 (s2)), vdest, 2); + vdest = pack_565 (invert_colors (load8888 (s3)), vdest, 3); + + *(__m64 *)dst = vdest; + } + else if (s0 | s1 | s2 | s3) + { + __m64 vdest = *(__m64 *)dst; + + vdest = pack_565 (over_rev_non_pre (load8888 (s0), expand565 (vdest, 0)), vdest, 0); + vdest = pack_565 (over_rev_non_pre (load8888 (s1), expand565 (vdest, 1)), vdest, 1); + vdest = pack_565 (over_rev_non_pre (load8888 (s2), expand565 (vdest, 2)), vdest, 2); + vdest = pack_565 (over_rev_non_pre (load8888 (s3), expand565 (vdest, 3)), vdest, 3); + + *(__m64 *)dst = vdest; + } + + w -= 4; + dst += 4; + src += 4; + } + + CHECKPOINT (); + + while (w) + { + __m64 vsrc = load8888 (*src); + uint64_t d = *dst; + __m64 vdest = expand565 (to_m64 (d), 0); + + vdest = pack_565 (over_rev_non_pre (vsrc, vdest), vdest, 0); + + *dst = to_uint64 (vdest); + + w--; + dst++; + src++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_pixbuf_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t *dst_line, *dst; + uint32_t *src_line, *src; + int dst_stride, src_stride; + int32_t w; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + +#if 0 + /* FIXME */ + assert (src_image->drawable == mask_image->drawable); +#endif + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + while (w && (unsigned long)dst & 7) + { + __m64 s = load8888 (*src); + __m64 d = load8888 (*dst); + + *dst = store8888 (over_rev_non_pre (s, d)); + + w--; + dst++; + src++; + } + + while (w >= 2) + { + uint64_t s0, s1; + unsigned char a0, a1; + __m64 d0, d1; + + s0 = *src; + s1 = *(src + 1); + + a0 = (s0 >> 24); + a1 = (s1 >> 24); + + if ((a0 & a1) == 0xFF) + { + d0 = invert_colors (load8888 (s0)); + d1 = invert_colors (load8888 (s1)); + + *(__m64 *)dst = pack8888 (d0, d1); + } + else if (s0 | s1) + { + __m64 vdest = *(__m64 *)dst; + + d0 = over_rev_non_pre (load8888 (s0), expand8888 (vdest, 0)); + d1 = over_rev_non_pre (load8888 (s1), expand8888 (vdest, 1)); + + *(__m64 *)dst = pack8888 (d0, d1); + } + + w -= 2; + dst += 2; + src += 2; + } + + while (w) + { + __m64 s = load8888 (*src); + __m64 d = load8888 (*dst); + + *dst = store8888 (over_rev_non_pre (s, d)); + + w--; + dst++; + src++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_over_n_8888_0565_ca (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src, srca; + uint16_t *dst_line; + uint32_t *mask_line; + int dst_stride, mask_stride; + __m64 vsrc, vsrca; + + CHECKPOINT (); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + srca = src >> 24; + if (src == 0) + return; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + int twidth = width; + uint32_t *p = (uint32_t *)mask_line; + uint16_t *q = (uint16_t *)dst_line; + + while (twidth && ((unsigned long)q & 7)) + { + uint32_t m = *(uint32_t *)p; + + if (m) + { + uint64_t d = *q; + __m64 vdest = expand565 (to_m64 (d), 0); + vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m), vdest), vdest, 0); + *q = to_uint64 (vdest); + } + + twidth--; + p++; + q++; + } + + while (twidth >= 4) + { + uint32_t m0, m1, m2, m3; + + m0 = *p; + m1 = *(p + 1); + m2 = *(p + 2); + m3 = *(p + 3); + + if ((m0 | m1 | m2 | m3)) + { + __m64 vdest = *(__m64 *)q; + + vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m0), expand565 (vdest, 0)), vdest, 0); + vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m1), expand565 (vdest, 1)), vdest, 1); + vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m2), expand565 (vdest, 2)), vdest, 2); + vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m3), expand565 (vdest, 3)), vdest, 3); + + *(__m64 *)q = vdest; + } + twidth -= 4; + p += 4; + q += 4; + } + + while (twidth) + { + uint32_t m; + + m = *(uint32_t *)p; + if (m) + { + uint64_t d = *q; + __m64 vdest = expand565 (to_m64 (d), 0); + vdest = pack_565 (in_over (vsrc, vsrca, load8888 (m), vdest), vdest, 0); + *q = to_uint64 (vdest); + } + + twidth--; + p++; + q++; + } + + mask_line += mask_stride; + dst_line += dst_stride; + } + + _mm_empty (); +} + +static void +mmx_composite_in_n_8_8 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint8_t *dst_line, *dst; + uint8_t *mask_line, *mask; + int dst_stride, mask_stride; + int32_t w; + uint32_t src; + uint8_t sa; + __m64 vsrc, vsrca; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + sa = src >> 24; + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + w = width; + + if ((((unsigned long)dst_image & 3) == 0) && + (((unsigned long)src_image & 3) == 0)) + { + while (w >= 4) + { + uint32_t m; + __m64 vmask; + __m64 vdest; + + m = 0; + + vmask = load8888 (*(uint32_t *)mask); + vdest = load8888 (*(uint32_t *)dst); + + *(uint32_t *)dst = store8888 (in (in (vsrca, vmask), vdest)); + + dst += 4; + mask += 4; + w -= 4; + } + } + + while (w--) + { + uint16_t tmp; + uint8_t a; + uint32_t m, d; + + a = *mask++; + d = *dst; + + m = MUL_UN8 (sa, a, tmp); + d = MUL_UN8 (m, d, tmp); + + *dst++ = d; + } + } + + _mm_empty (); +} + +static void +mmx_composite_in_8_8 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint8_t *dst_line, *dst; + uint8_t *src_line, *src; + int src_stride, dst_stride; + int32_t w; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + if ((((unsigned long)dst_image & 3) == 0) && + (((unsigned long)src_image & 3) == 0)) + { + while (w >= 4) + { + uint32_t *s = (uint32_t *)src; + uint32_t *d = (uint32_t *)dst; + + *d = store8888 (in (load8888 (*s), load8888 (*d))); + + w -= 4; + dst += 4; + src += 4; + } + } + + while (w--) + { + uint8_t s, d; + uint16_t tmp; + + s = *src; + d = *dst; + + *dst = MUL_UN8 (s, d, tmp); + + src++; + dst++; + } + } + + _mm_empty (); +} + +static void +mmx_composite_add_n_8_8 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint8_t *dst_line, *dst; + uint8_t *mask_line, *mask; + int dst_stride, mask_stride; + int32_t w; + uint32_t src; + uint8_t sa; + __m64 vsrc, vsrca; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); + + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); + + sa = src >> 24; + + if (src == 0) + return; + + vsrc = load8888 (src); + vsrca = expand_alpha (vsrc); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + w = width; + + if ((((unsigned long)mask_image & 3) == 0) && + (((unsigned long)dst_image & 3) == 0)) + { + while (w >= 4) + { + __m64 vmask = load8888 (*(uint32_t *)mask); + __m64 vdest = load8888 (*(uint32_t *)dst); + + *(uint32_t *)dst = store8888 (_mm_adds_pu8 (in (vsrca, vmask), vdest)); + + w -= 4; + dst += 4; + mask += 4; + } + } + + while (w--) + { + uint16_t tmp; + uint16_t a; + uint32_t m, d; + uint32_t r; + + a = *mask++; + d = *dst; + + m = MUL_UN8 (sa, a, tmp); + r = ADD_UN8 (m, d, tmp); + + *dst++ = r; + } + } + + _mm_empty (); +} + +static void +mmx_composite_add_8_8 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint8_t *dst_line, *dst; + uint8_t *src_line, *src; + int dst_stride, src_stride; + int32_t w; + uint8_t s, d; + uint16_t t; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + while (w && (unsigned long)dst & 7) + { + s = *src; + d = *dst; + t = d + s; + s = t | (0 - (t >> 8)); + *dst = s; + + dst++; + src++; + w--; + } + + while (w >= 8) + { + *(__m64*)dst = _mm_adds_pu8 (*(__m64*)src, *(__m64*)dst); + dst += 8; + src += 8; + w -= 8; + } + + while (w) + { + s = *src; + d = *dst; + t = d + s; + s = t | (0 - (t >> 8)); + *dst = s; + + dst++; + src++; + w--; + } + } + + _mm_empty (); +} + +static void +mmx_composite_add_8888_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + __m64 dst64; + uint32_t *dst_line, *dst; + uint32_t *src_line, *src; + int dst_stride, src_stride; + int32_t w; + + CHECKPOINT (); + + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + src = src_line; + src_line += src_stride; + w = width; + + while (w && (unsigned long)dst & 7) + { + *dst = _mm_cvtsi64_si32 (_mm_adds_pu8 (_mm_cvtsi32_si64 (*src), + _mm_cvtsi32_si64 (*dst))); + dst++; + src++; + w--; + } + + while (w >= 2) + { + dst64 = _mm_adds_pu8 (*(__m64*)src, *(__m64*)dst); + *(uint64_t*)dst = to_uint64 (dst64); + dst += 2; + src += 2; + w -= 2; + } + + if (w) + { + *dst = _mm_cvtsi64_si32 (_mm_adds_pu8 (_mm_cvtsi32_si64 (*src), + _mm_cvtsi32_si64 (*dst))); + + } + } + + _mm_empty (); +} + +static pixman_bool_t +pixman_blt_mmx (uint32_t *src_bits, + uint32_t *dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height) +{ + uint8_t * src_bytes; + uint8_t * dst_bytes; + int byte_width; + + if (src_bpp != dst_bpp) + return FALSE; + + if (src_bpp == 16) + { + src_stride = src_stride * (int) sizeof (uint32_t) / 2; + dst_stride = dst_stride * (int) sizeof (uint32_t) / 2; + src_bytes = (uint8_t *)(((uint16_t *)src_bits) + src_stride * (src_y) + (src_x)); + dst_bytes = (uint8_t *)(((uint16_t *)dst_bits) + dst_stride * (dst_y) + (dst_x)); + byte_width = 2 * width; + src_stride *= 2; + dst_stride *= 2; + } + else if (src_bpp == 32) + { + src_stride = src_stride * (int) sizeof (uint32_t) / 4; + dst_stride = dst_stride * (int) sizeof (uint32_t) / 4; + src_bytes = (uint8_t *)(((uint32_t *)src_bits) + src_stride * (src_y) + (src_x)); + dst_bytes = (uint8_t *)(((uint32_t *)dst_bits) + dst_stride * (dst_y) + (dst_x)); + byte_width = 4 * width; + src_stride *= 4; + dst_stride *= 4; + } + else + { + return FALSE; + } + + while (height--) + { + int w; + uint8_t *s = src_bytes; + uint8_t *d = dst_bytes; + src_bytes += src_stride; + dst_bytes += dst_stride; + w = byte_width; + + while (w >= 2 && ((unsigned long)d & 3)) + { + *(uint16_t *)d = *(uint16_t *)s; + w -= 2; + s += 2; + d += 2; + } + + while (w >= 4 && ((unsigned long)d & 7)) + { + *(uint32_t *)d = *(uint32_t *)s; + + w -= 4; + s += 4; + d += 4; + } + + while (w >= 64) + { +#if defined (__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) + __asm__ ( + "movq (%1), %%mm0\n" + "movq 8(%1), %%mm1\n" + "movq 16(%1), %%mm2\n" + "movq 24(%1), %%mm3\n" + "movq 32(%1), %%mm4\n" + "movq 40(%1), %%mm5\n" + "movq 48(%1), %%mm6\n" + "movq 56(%1), %%mm7\n" + + "movq %%mm0, (%0)\n" + "movq %%mm1, 8(%0)\n" + "movq %%mm2, 16(%0)\n" + "movq %%mm3, 24(%0)\n" + "movq %%mm4, 32(%0)\n" + "movq %%mm5, 40(%0)\n" + "movq %%mm6, 48(%0)\n" + "movq %%mm7, 56(%0)\n" + : + : "r" (d), "r" (s) + : "memory", + "%mm0", "%mm1", "%mm2", "%mm3", + "%mm4", "%mm5", "%mm6", "%mm7"); +#else + __m64 v0 = *(__m64 *)(s + 0); + __m64 v1 = *(__m64 *)(s + 8); + __m64 v2 = *(__m64 *)(s + 16); + __m64 v3 = *(__m64 *)(s + 24); + __m64 v4 = *(__m64 *)(s + 32); + __m64 v5 = *(__m64 *)(s + 40); + __m64 v6 = *(__m64 *)(s + 48); + __m64 v7 = *(__m64 *)(s + 56); + *(__m64 *)(d + 0) = v0; + *(__m64 *)(d + 8) = v1; + *(__m64 *)(d + 16) = v2; + *(__m64 *)(d + 24) = v3; + *(__m64 *)(d + 32) = v4; + *(__m64 *)(d + 40) = v5; + *(__m64 *)(d + 48) = v6; + *(__m64 *)(d + 56) = v7; +#endif + + w -= 64; + s += 64; + d += 64; + } + while (w >= 4) + { + *(uint32_t *)d = *(uint32_t *)s; + + w -= 4; + s += 4; + d += 4; + } + if (w >= 2) + { + *(uint16_t *)d = *(uint16_t *)s; + w -= 2; + s += 2; + d += 2; + } + } + + _mm_empty (); + + return TRUE; +} + +static void +mmx_composite_copy_area (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + pixman_blt_mmx (src_image->bits.bits, + dst_image->bits.bits, + src_image->bits.rowstride, + dst_image->bits.rowstride, + PIXMAN_FORMAT_BPP (src_image->bits.format), + PIXMAN_FORMAT_BPP (dst_image->bits.format), + src_x, src_y, dest_x, dest_y, width, height); +} + +#if 0 +static void +mmx_composite_over_x888_8_8888 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t *src, *src_line; + uint32_t *dst, *dst_line; + uint8_t *mask, *mask_line; + int src_stride, mask_stride, dst_stride; + int32_t w; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); + PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); + + while (height--) + { + src = src_line; + src_line += src_stride; + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + + w = width; + + while (w--) + { + uint64_t m = *mask; + + if (m) + { + __m64 s = load8888 (*src | 0xff000000); + + if (m == 0xff) + { + *dst = store8888 (s); + } + else + { + __m64 sa = expand_alpha (s); + __m64 vm = expand_alpha_rev (to_m64 (m)); + __m64 vdest = in_over (s, sa, vm, load8888 (*dst)); + + *dst = store8888 (vdest); + } + } + + mask++; + dst++; + src++; + } + } + + _mm_empty (); +} +#endif + +static const pixman_fast_path_t mmx_fast_paths[] = +{ + PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mmx_composite_over_n_8_0565 ), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mmx_composite_over_n_8_0565 ), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, mmx_composite_over_n_8_8888 ), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, mmx_composite_over_n_8_8888 ), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, mmx_composite_over_n_8_8888 ), + PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, mmx_composite_over_n_8_8888 ), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mmx_composite_over_n_8888_8888_ca ), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mmx_composite_over_n_8888_8888_ca ), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, mmx_composite_over_n_8888_0565_ca ), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mmx_composite_over_n_8888_8888_ca ), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mmx_composite_over_n_8888_8888_ca ), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, mmx_composite_over_n_8888_0565_ca ), + PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, a8r8g8b8, mmx_composite_over_pixbuf_8888 ), + PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, x8r8g8b8, mmx_composite_over_pixbuf_8888 ), + PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, r5g6b5, mmx_composite_over_pixbuf_0565 ), + PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, a8b8g8r8, mmx_composite_over_pixbuf_8888 ), + PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, x8b8g8r8, mmx_composite_over_pixbuf_8888 ), + PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, b5g6r5, mmx_composite_over_pixbuf_0565 ), + PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, a8r8g8b8, mmx_composite_over_x888_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, x8r8g8b8, mmx_composite_over_x888_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, a8b8g8r8, mmx_composite_over_x888_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, x8b8g8r8, mmx_composite_over_x888_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mmx_composite_over_8888_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mmx_composite_over_8888_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, mmx_composite_over_8888_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, mmx_composite_over_8888_n_8888 ), +#if 0 + /* FIXME: This code is commented out since it's apparently + * not actually faster than the generic code. + */ + PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, mmx_composite_over_x888_8_8888 ), + PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, mmx_composite_over_x888_8_8888 ), + PIXMAN_STD_FAST_PATH (OVER, x8b8r8g8, a8, x8b8g8r8, mmx_composite_over_x888_8_8888 ), + PIXMAN_STD_FAST_PATH (OVER, x8b8r8g8, a8, a8r8g8b8, mmx_composite_over_x888_8_8888 ), +#endif + PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, mmx_composite_over_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, mmx_composite_over_n_8888 ), + PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, mmx_composite_over_n_0565 ), + PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ), + + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mmx_composite_over_8888_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mmx_composite_over_8888_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, mmx_composite_over_8888_0565 ), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mmx_composite_over_8888_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mmx_composite_over_8888_8888 ), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, mmx_composite_over_8888_0565 ), + + PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, mmx_composite_add_8888_8888 ), + PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, mmx_composite_add_8888_8888 ), + PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, mmx_composite_add_8_8 ), + PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, mmx_composite_add_n_8_8 ), + + PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, mmx_composite_src_n_8_8888 ), + PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, mmx_composite_src_n_8_8888 ), + PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, mmx_composite_src_n_8_8888 ), + PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, mmx_composite_src_n_8_8888 ), + PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, mmx_composite_copy_area ), + PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, mmx_composite_copy_area ), + + PIXMAN_STD_FAST_PATH (IN, a8, null, a8, mmx_composite_in_8_8 ), + PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, mmx_composite_in_n_8_8 ), + + { PIXMAN_OP_NONE }, +}; + +static pixman_bool_t +mmx_blt (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height) +{ + if (!pixman_blt_mmx ( + src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, + src_x, src_y, dst_x, dst_y, width, height)) + + { + return _pixman_implementation_blt ( + imp->delegate, + src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, + src_x, src_y, dst_x, dst_y, width, height); + } + + return TRUE; +} + +static pixman_bool_t +mmx_fill (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) +{ + if (!pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor)) + { + return _pixman_implementation_fill ( + imp->delegate, bits, stride, bpp, x, y, width, height, xor); + } + + return TRUE; +} + +pixman_implementation_t * +_pixman_implementation_create_mmx (void) +{ + pixman_implementation_t *general = _pixman_implementation_create_fast_path (); + pixman_implementation_t *imp = _pixman_implementation_create (general, mmx_fast_paths); + + imp->combine_32[PIXMAN_OP_OVER] = mmx_combine_over_u; + imp->combine_32[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_u; + imp->combine_32[PIXMAN_OP_IN] = mmx_combine_in_u; + imp->combine_32[PIXMAN_OP_IN_REVERSE] = mmx_combine_in_reverse_u; + imp->combine_32[PIXMAN_OP_OUT] = mmx_combine_out_u; + imp->combine_32[PIXMAN_OP_OUT_REVERSE] = mmx_combine_out_reverse_u; + imp->combine_32[PIXMAN_OP_ATOP] = mmx_combine_atop_u; + imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = mmx_combine_atop_reverse_u; + imp->combine_32[PIXMAN_OP_XOR] = mmx_combine_xor_u; + imp->combine_32[PIXMAN_OP_ADD] = mmx_combine_add_u; + imp->combine_32[PIXMAN_OP_SATURATE] = mmx_combine_saturate_u; + + imp->combine_32_ca[PIXMAN_OP_SRC] = mmx_combine_src_ca; + imp->combine_32_ca[PIXMAN_OP_OVER] = mmx_combine_over_ca; + imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_ca; + imp->combine_32_ca[PIXMAN_OP_IN] = mmx_combine_in_ca; + imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = mmx_combine_in_reverse_ca; + imp->combine_32_ca[PIXMAN_OP_OUT] = mmx_combine_out_ca; + imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = mmx_combine_out_reverse_ca; + imp->combine_32_ca[PIXMAN_OP_ATOP] = mmx_combine_atop_ca; + imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = mmx_combine_atop_reverse_ca; + imp->combine_32_ca[PIXMAN_OP_XOR] = mmx_combine_xor_ca; + imp->combine_32_ca[PIXMAN_OP_ADD] = mmx_combine_add_ca; + + imp->blt = mmx_blt; + imp->fill = mmx_fill; + + return imp; +} + +#endif /* USE_MMX */ diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index b6eb24835..1662d2c46 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -1,867 +1,912 @@ -#ifndef PACKAGE
-# error config.h must be included before pixman-private.h
-#endif
-
-#ifndef PIXMAN_PRIVATE_H
-#define PIXMAN_PRIVATE_H
-
-#define PIXMAN_DISABLE_DEPRECATED
-#define PIXMAN_USE_INTERNAL_API
-
-#include "pixman.h"
-#include <time.h>
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "pixman-compiler.h"
-
-/*
- * Images
- */
-typedef struct image_common image_common_t;
-typedef struct solid_fill solid_fill_t;
-typedef struct gradient gradient_t;
-typedef struct linear_gradient linear_gradient_t;
-typedef struct horizontal_gradient horizontal_gradient_t;
-typedef struct vertical_gradient vertical_gradient_t;
-typedef struct conical_gradient conical_gradient_t;
-typedef struct radial_gradient radial_gradient_t;
-typedef struct bits_image bits_image_t;
-typedef struct circle circle_t;
-
-typedef void (*fetch_scanline_t) (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t *buffer,
- const uint32_t *mask);
-
-typedef uint32_t (*fetch_pixel_32_t) (bits_image_t *image,
- int x,
- int y);
-
-typedef uint64_t (*fetch_pixel_64_t) (bits_image_t *image,
- int x,
- int y);
-
-typedef void (*store_scanline_t) (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values);
-
-typedef enum
-{
- BITS,
- LINEAR,
- CONICAL,
- RADIAL,
- SOLID
-} image_type_t;
-
-typedef enum
-{
- SOURCE_IMAGE_CLASS_UNKNOWN,
- SOURCE_IMAGE_CLASS_HORIZONTAL,
-} source_image_class_t;
-
-typedef source_image_class_t (*classify_func_t) (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height);
-typedef void (*property_changed_func_t) (pixman_image_t *image);
-
-struct image_common
-{
- image_type_t type;
- int32_t ref_count;
- pixman_region32_t clip_region;
- int32_t alpha_count; /* How many times this image is being used as an alpha map */
- pixman_bool_t have_clip_region; /* FALSE if there is no clip */
- pixman_bool_t client_clip; /* Whether the source clip was
- set by a client */
- pixman_bool_t clip_sources; /* Whether the clip applies when
- * the image is used as a source
- */
- pixman_bool_t dirty;
- pixman_transform_t * transform;
- pixman_repeat_t repeat;
- pixman_filter_t filter;
- pixman_fixed_t * filter_params;
- int n_filter_params;
- bits_image_t * alpha_map;
- int alpha_origin_x;
- int alpha_origin_y;
- pixman_bool_t component_alpha;
- classify_func_t classify;
- property_changed_func_t property_changed;
- fetch_scanline_t get_scanline_32;
- fetch_scanline_t get_scanline_64;
-
- pixman_image_destroy_func_t destroy_func;
- void * destroy_data;
-
- uint32_t flags;
- pixman_format_code_t extended_format_code;
-};
-
-struct solid_fill
-{
- image_common_t common;
- pixman_color_t color;
-
- uint32_t color_32;
- uint64_t color_64;
-};
-
-struct gradient
-{
- image_common_t common;
- int n_stops;
- pixman_gradient_stop_t *stops;
-};
-
-struct linear_gradient
-{
- gradient_t common;
- pixman_point_fixed_t p1;
- pixman_point_fixed_t p2;
-};
-
-struct circle
-{
- pixman_fixed_t x;
- pixman_fixed_t y;
- pixman_fixed_t radius;
-};
-
-struct radial_gradient
-{
- gradient_t common;
-
- circle_t c1;
- circle_t c2;
-
- circle_t delta;
- double a;
- double inva;
- double mindr;
-};
-
-struct conical_gradient
-{
- gradient_t common;
- pixman_point_fixed_t center;
- double angle;
-};
-
-struct bits_image
-{
- image_common_t common;
- pixman_format_code_t format;
- const pixman_indexed_t * indexed;
- int width;
- int height;
- uint32_t * bits;
- uint32_t * free_me;
- int rowstride; /* in number of uint32_t's */
-
- fetch_scanline_t fetch_scanline_32;
- fetch_pixel_32_t fetch_pixel_32;
- store_scanline_t store_scanline_32;
-
- fetch_scanline_t fetch_scanline_64;
- fetch_pixel_64_t fetch_pixel_64;
- store_scanline_t store_scanline_64;
-
- /* Used for indirect access to the bits */
- pixman_read_memory_func_t read_func;
- pixman_write_memory_func_t write_func;
-};
-
-union pixman_image
-{
- image_type_t type;
- image_common_t common;
- bits_image_t bits;
- gradient_t gradient;
- linear_gradient_t linear;
- conical_gradient_t conical;
- radial_gradient_t radial;
- solid_fill_t solid;
-};
-
-void
-_pixman_bits_image_setup_accessors (bits_image_t *image);
-
-void
-_pixman_image_get_scanline_generic_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask);
-
-source_image_class_t
-_pixman_image_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height);
-
-void
-_pixman_image_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask);
-
-/* Even thought the type of buffer is uint32_t *, the function actually expects
- * a uint64_t *buffer.
- */
-void
-_pixman_image_get_scanline_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *unused);
-
-void
-_pixman_image_store_scanline_32 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
-/* Even though the type of buffer is uint32_t *, the function
- * actually expects a uint64_t *buffer.
- */
-void
-_pixman_image_store_scanline_64 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
-pixman_image_t *
-_pixman_image_allocate (void);
-
-pixman_bool_t
-_pixman_init_gradient (gradient_t * gradient,
- const pixman_gradient_stop_t *stops,
- int n_stops);
-void
-_pixman_image_reset_clip_region (pixman_image_t *image);
-
-void
-_pixman_image_validate (pixman_image_t *image);
-
-uint32_t
-_pixman_image_get_solid (pixman_image_t * image,
- pixman_format_code_t format);
-
-#define PIXMAN_IMAGE_GET_LINE(image, x, y, type, out_stride, line, mul) \
- do \
- { \
- uint32_t *__bits__; \
- int __stride__; \
- \
- __bits__ = image->bits.bits; \
- __stride__ = image->bits.rowstride; \
- (out_stride) = \
- __stride__ * (int) sizeof (uint32_t) / (int) sizeof (type); \
- (line) = \
- ((type *) __bits__) + (out_stride) * (y) + (mul) * (x); \
- } while (0)
-
-/*
- * Gradient walker
- */
-typedef struct
-{
- uint32_t left_ag;
- uint32_t left_rb;
- uint32_t right_ag;
- uint32_t right_rb;
- int32_t left_x;
- int32_t right_x;
- int32_t stepper;
-
- pixman_gradient_stop_t *stops;
- int num_stops;
- unsigned int spread;
-
- int need_reset;
-} pixman_gradient_walker_t;
-
-void
-_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
- gradient_t * gradient,
- unsigned int spread);
-
-void
-_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t pos);
-
-uint32_t
-_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t x);
-
-/*
- * Edges
- */
-
-#define MAX_ALPHA(n) ((1 << (n)) - 1)
-#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)
-#define N_X_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) + 1)
-
-#define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC (n))
-#define STEP_Y_BIG(n) (pixman_fixed_1 - (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
-
-#define Y_FRAC_FIRST(n) (STEP_Y_BIG (n) / 2)
-#define Y_FRAC_LAST(n) (Y_FRAC_FIRST (n) + (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
-
-#define STEP_X_SMALL(n) (pixman_fixed_1 / N_X_FRAC (n))
-#define STEP_X_BIG(n) (pixman_fixed_1 - (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
-
-#define X_FRAC_FIRST(n) (STEP_X_BIG (n) / 2)
-#define X_FRAC_LAST(n) (X_FRAC_FIRST (n) + (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
-
-#define RENDER_SAMPLES_X(x, n) \
- ((n) == 1? 0 : (pixman_fixed_frac (x) + \
- X_FRAC_FIRST (n)) / STEP_X_SMALL (n))
-
-void
-pixman_rasterize_edges_accessors (pixman_image_t *image,
- pixman_edge_t * l,
- pixman_edge_t * r,
- pixman_fixed_t t,
- pixman_fixed_t b);
-
-/*
- * Implementations
- */
-typedef struct pixman_implementation_t pixman_implementation_t;
-
-typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width);
-
-typedef void (*pixman_combine_64_func_t) (pixman_implementation_t *imp,
- pixman_op_t op,
- uint64_t * dest,
- const uint64_t * src,
- const uint64_t * mask,
- int width);
-
-typedef void (*pixman_composite_func_t) (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height);
-typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp,
- uint32_t * src_bits,
- uint32_t * dst_bits,
- int src_stride,
- int dst_stride,
- int src_bpp,
- int dst_bpp,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height);
-typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
- uint32_t * bits,
- int stride,
- int bpp,
- int x,
- int y,
- int width,
- int height,
- uint32_t xor);
-
-void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
-void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp);
-
-typedef struct
-{
- pixman_op_t op;
- pixman_format_code_t src_format;
- uint32_t src_flags;
- pixman_format_code_t mask_format;
- uint32_t mask_flags;
- pixman_format_code_t dest_format;
- uint32_t dest_flags;
- pixman_composite_func_t func;
-} pixman_fast_path_t;
-
-struct pixman_implementation_t
-{
- pixman_implementation_t * toplevel;
- pixman_implementation_t * delegate;
- const pixman_fast_path_t * fast_paths;
-
- pixman_blt_func_t blt;
- pixman_fill_func_t fill;
-
- pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS];
- pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS];
- pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS];
- pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS];
-};
-
-pixman_implementation_t *
-_pixman_implementation_create (pixman_implementation_t *delegate,
- const pixman_fast_path_t *fast_paths);
-
-void
-_pixman_implementation_combine_32 (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width);
-void
-_pixman_implementation_combine_64 (pixman_implementation_t *imp,
- pixman_op_t op,
- uint64_t * dest,
- const uint64_t * src,
- const uint64_t * mask,
- int width);
-void
-_pixman_implementation_combine_32_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width);
-void
-_pixman_implementation_combine_64_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint64_t * dest,
- const uint64_t * src,
- const uint64_t * mask,
- int width);
-
-pixman_bool_t
-_pixman_implementation_blt (pixman_implementation_t *imp,
- uint32_t * src_bits,
- uint32_t * dst_bits,
- int src_stride,
- int dst_stride,
- int src_bpp,
- int dst_bpp,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height);
-
-pixman_bool_t
-_pixman_implementation_fill (pixman_implementation_t *imp,
- uint32_t * bits,
- int stride,
- int bpp,
- int x,
- int y,
- int width,
- int height,
- uint32_t xor);
-
-/* Specific implementations */
-pixman_implementation_t *
-_pixman_implementation_create_general (void);
-
-pixman_implementation_t *
-_pixman_implementation_create_fast_path (void);
-
-#ifdef USE_MMX
-pixman_implementation_t *
-_pixman_implementation_create_mmx (void);
-#endif
-
-#ifdef USE_SSE2
-pixman_implementation_t *
-_pixman_implementation_create_sse2 (void);
-#endif
-
-#ifdef USE_ARM_SIMD
-pixman_implementation_t *
-_pixman_implementation_create_arm_simd (void);
-#endif
-
-#ifdef USE_ARM_NEON
-pixman_implementation_t *
-_pixman_implementation_create_arm_neon (void);
-#endif
-
-#ifdef USE_VMX
-pixman_implementation_t *
-_pixman_implementation_create_vmx (void);
-#endif
-
-pixman_implementation_t *
-_pixman_choose_implementation (void);
-
-
-
-/*
- * Utilities
- */
-
-/* These "formats" all have depth 0, so they
- * will never clash with any real ones
- */
-#define PIXMAN_null PIXMAN_FORMAT (0, 0, 0, 0, 0, 0)
-#define PIXMAN_solid PIXMAN_FORMAT (0, 1, 0, 0, 0, 0)
-#define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0)
-#define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0)
-#define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0)
-#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0)
-
-#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1)
-
-#define FAST_PATH_ID_TRANSFORM (1 << 0)
-#define FAST_PATH_NO_ALPHA_MAP (1 << 1)
-#define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2)
-#define FAST_PATH_NO_PAD_REPEAT (1 << 3)
-#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4)
-#define FAST_PATH_NO_ACCESSORS (1 << 5)
-#define FAST_PATH_NARROW_FORMAT (1 << 6)
-#define FAST_PATH_COMPONENT_ALPHA (1 << 8)
-#define FAST_PATH_SAMPLES_OPAQUE (1 << 7)
-#define FAST_PATH_UNIFIED_ALPHA (1 << 9)
-#define FAST_PATH_SCALE_TRANSFORM (1 << 10)
-#define FAST_PATH_NEAREST_FILTER (1 << 11)
-#define FAST_PATH_HAS_TRANSFORM (1 << 12)
-#define FAST_PATH_IS_OPAQUE (1 << 13)
-#define FAST_PATH_NO_NORMAL_REPEAT (1 << 14)
-#define FAST_PATH_NO_NONE_REPEAT (1 << 15)
-#define FAST_PATH_SAMPLES_COVER_CLIP (1 << 16)
-#define FAST_PATH_X_UNIT_POSITIVE (1 << 17)
-#define FAST_PATH_AFFINE_TRANSFORM (1 << 18)
-#define FAST_PATH_Y_UNIT_ZERO (1 << 19)
-#define FAST_PATH_BILINEAR_FILTER (1 << 20)
-
-#define FAST_PATH_PAD_REPEAT \
- (FAST_PATH_NO_NONE_REPEAT | \
- FAST_PATH_NO_NORMAL_REPEAT | \
- FAST_PATH_NO_REFLECT_REPEAT)
-
-#define FAST_PATH_NORMAL_REPEAT \
- (FAST_PATH_NO_NONE_REPEAT | \
- FAST_PATH_NO_PAD_REPEAT | \
- FAST_PATH_NO_REFLECT_REPEAT)
-
-#define FAST_PATH_NONE_REPEAT \
- (FAST_PATH_NO_NORMAL_REPEAT | \
- FAST_PATH_NO_PAD_REPEAT | \
- FAST_PATH_NO_REFLECT_REPEAT)
-
-#define FAST_PATH_REFLECT_REPEAT \
- (FAST_PATH_NO_NONE_REPEAT | \
- FAST_PATH_NO_NORMAL_REPEAT | \
- FAST_PATH_NO_PAD_REPEAT)
-
-#define FAST_PATH_STANDARD_FLAGS \
- (FAST_PATH_NO_CONVOLUTION_FILTER | \
- FAST_PATH_NO_ACCESSORS | \
- FAST_PATH_NO_ALPHA_MAP | \
- FAST_PATH_NARROW_FORMAT)
-
-#define FAST_PATH_STD_DEST_FLAGS \
- (FAST_PATH_NO_ACCESSORS | \
- FAST_PATH_NO_ALPHA_MAP | \
- FAST_PATH_NARROW_FORMAT)
-
-#define SOURCE_FLAGS(format) \
- (FAST_PATH_STANDARD_FLAGS | \
- ((PIXMAN_ ## format == PIXMAN_solid) ? \
- 0 : (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_ID_TRANSFORM)))
-
-#define MASK_FLAGS(format, extra) \
- ((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra))
-
-#define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \
- PIXMAN_OP_ ## op, \
- PIXMAN_ ## src, \
- src_flags, \
- PIXMAN_ ## mask, \
- mask_flags, \
- PIXMAN_ ## dest, \
- dest_flags, \
- func
-
-#define PIXMAN_STD_FAST_PATH(op, src, mask, dest, func) \
- { FAST_PATH ( \
- op, \
- src, SOURCE_FLAGS (src), \
- mask, MASK_FLAGS (mask, FAST_PATH_UNIFIED_ALPHA), \
- dest, FAST_PATH_STD_DEST_FLAGS, \
- func) }
-
-#define PIXMAN_STD_FAST_PATH_CA(op, src, mask, dest, func) \
- { FAST_PATH ( \
- op, \
- src, SOURCE_FLAGS (src), \
- mask, MASK_FLAGS (mask, FAST_PATH_COMPONENT_ALPHA), \
- dest, FAST_PATH_STD_DEST_FLAGS, \
- func) }
-
-/* Memory allocation helpers */
-void *
-pixman_malloc_ab (unsigned int n, unsigned int b);
-
-void *
-pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
-
-pixman_bool_t
-pixman_multiply_overflows_int (unsigned int a, unsigned int b);
-
-pixman_bool_t
-pixman_addition_overflows_int (unsigned int a, unsigned int b);
-
-/* Compositing utilities */
-void
-pixman_expand (uint64_t * dst,
- const uint32_t * src,
- pixman_format_code_t format,
- int width);
-
-void
-pixman_contract (uint32_t * dst,
- const uint64_t *src,
- int width);
-
-
-/* Region Helpers */
-pixman_bool_t
-pixman_region32_copy_from_region16 (pixman_region32_t *dst,
- pixman_region16_t *src);
-
-pixman_bool_t
-pixman_region16_copy_from_region32 (pixman_region16_t *dst,
- pixman_region32_t *src);
-
-
-/* Misc macros */
-
-#ifndef FALSE
-# define FALSE 0
-#endif
-
-#ifndef TRUE
-# define TRUE 1
-#endif
-
-#ifndef MIN
-# define MIN(a, b) ((a < b) ? a : b)
-#endif
-
-#ifndef MAX
-# define MAX(a, b) ((a > b) ? a : b)
-#endif
-
-/* Integer division that rounds towards -infinity */
-#define DIV(a, b) \
- ((((a) < 0) == ((b) < 0)) ? (a) / (b) : \
- ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
-
-/* Modulus that produces the remainder wrt. DIV */
-#define MOD(a, b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
-
-#define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v)))
-
-/* Conversion between 8888 and 0565 */
-
-#define CONVERT_8888_TO_0565(s) \
- ((((s) >> 3) & 0x001f) | \
- (((s) >> 5) & 0x07e0) | \
- (((s) >> 8) & 0xf800))
-
-#define CONVERT_0565_TO_0888(s) \
- (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
- ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
- ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
-
-#define CONVERT_0565_TO_8888(s) (CONVERT_0565_TO_0888(s) | 0xff000000)
-
-/* Trivial versions that are useful in macros */
-#define CONVERT_8888_TO_8888(s) (s)
-#define CONVERT_0565_TO_0565(s) (s)
-
-#define PIXMAN_FORMAT_IS_WIDE(f) \
- (PIXMAN_FORMAT_A (f) > 8 || \
- PIXMAN_FORMAT_R (f) > 8 || \
- PIXMAN_FORMAT_G (f) > 8 || \
- PIXMAN_FORMAT_B (f) > 8)
-
-#ifdef WORDS_BIGENDIAN
-# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
-# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
-#else
-# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
-# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
-#endif
-
-/*
- * Various debugging code
- */
-
-#undef DEBUG
-
-#define COMPILE_TIME_ASSERT(x) \
- do { typedef int compile_time_assertion [(x)?1:-1]; } while (0)
-
-/* Turn on debugging depending on what type of release this is
- */
-#if (((PIXMAN_VERSION_MICRO % 2) == 0) && ((PIXMAN_VERSION_MINOR % 2) == 1))
-
-/* Debugging gets turned on for development releases because these
- * are the things that end up in bleeding edge distributions such
- * as Rawhide etc.
- *
- * For performance reasons we don't turn it on for stable releases or
- * random git checkouts. (Random git checkouts are often used for
- * performance work).
- */
-
-# define DEBUG
-
-#endif
-
-#ifdef DEBUG
-
-void
-_pixman_log_error (const char *function, const char *message);
-
-#define return_if_fail(expr) \
- do \
- { \
- if (!(expr)) \
- { \
- _pixman_log_error (FUNC, "The expression " # expr " was false"); \
- return; \
- } \
- } \
- while (0)
-
-#define return_val_if_fail(expr, retval) \
- do \
- { \
- if (!(expr)) \
- { \
- _pixman_log_error (FUNC, "The expression " # expr " was false"); \
- return (retval); \
- } \
- } \
- while (0)
-
-#define critical_if_fail(expr) \
- do \
- { \
- if (!(expr)) \
- _pixman_log_error (FUNC, "The expression " # expr " was false"); \
- } \
- while (0)
-
-
-#else
-
-#define _pixman_log_error(f,m) do { } while (0) \
-
-#define return_if_fail(expr) \
- do \
- { \
- if (!(expr)) \
- return; \
- } \
- while (0)
-
-#define return_val_if_fail(expr, retval) \
- do \
- { \
- if (!(expr)) \
- return (retval); \
- } \
- while (0)
-
-#define critical_if_fail(expr) \
- do \
- { \
- } \
- while (0)
-#endif
-
-/*
- * Timers
- */
-
-#ifdef PIXMAN_TIMERS
-
-static inline uint64_t
-oil_profile_stamp_rdtsc (void)
-{
- uint64_t ts;
-
- __asm__ __volatile__ ("rdtsc\n" : "=A" (ts));
- return ts;
-}
-
-#define OIL_STAMP oil_profile_stamp_rdtsc
-
-typedef struct pixman_timer_t pixman_timer_t;
-
-struct pixman_timer_t
-{
- int initialized;
- const char * name;
- uint64_t n_times;
- uint64_t total;
- pixman_timer_t *next;
-};
-
-extern int timer_defined;
-
-void pixman_timer_register (pixman_timer_t *timer);
-
-#define TIMER_BEGIN(tname) \
- { \
- static pixman_timer_t timer ## tname; \
- uint64_t begin ## tname; \
- \
- if (!timer ## tname.initialized) \
- { \
- timer ## tname.initialized = 1; \
- timer ## tname.name = # tname; \
- pixman_timer_register (&timer ## tname); \
- } \
- \
- timer ## tname.n_times++; \
- begin ## tname = OIL_STAMP ();
-
-#define TIMER_END(tname) \
- timer ## tname.total += OIL_STAMP () - begin ## tname; \
- }
-
-#endif /* PIXMAN_TIMERS */
-
-#endif /* PIXMAN_PRIVATE_H */
+#ifndef PACKAGE +# error config.h must be included before pixman-private.h +#endif + +#ifndef PIXMAN_PRIVATE_H +#define PIXMAN_PRIVATE_H + +#define PIXMAN_DISABLE_DEPRECATED +#define PIXMAN_USE_INTERNAL_API + +#include "pixman.h" +#include <time.h> +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#include "pixman-compiler.h" + +/* + * Images + */ +typedef struct image_common image_common_t; +typedef struct solid_fill solid_fill_t; +typedef struct gradient gradient_t; +typedef struct linear_gradient linear_gradient_t; +typedef struct horizontal_gradient horizontal_gradient_t; +typedef struct vertical_gradient vertical_gradient_t; +typedef struct conical_gradient conical_gradient_t; +typedef struct radial_gradient radial_gradient_t; +typedef struct bits_image bits_image_t; +typedef struct circle circle_t; + +typedef void (*fetch_scanline_t) (pixman_image_t *image, + int x, + int y, + int width, + uint32_t *buffer, + const uint32_t *mask); + +typedef uint32_t (*fetch_pixel_32_t) (bits_image_t *image, + int x, + int y); + +typedef uint64_t (*fetch_pixel_64_t) (bits_image_t *image, + int x, + int y); + +typedef void (*store_scanline_t) (bits_image_t * image, + int x, + int y, + int width, + const uint32_t *values); + +typedef enum +{ + BITS, + LINEAR, + CONICAL, + RADIAL, + SOLID +} image_type_t; + +typedef void (*property_changed_func_t) (pixman_image_t *image); + +struct image_common +{ + image_type_t type; + int32_t ref_count; + pixman_region32_t clip_region; + int32_t alpha_count; /* How many times this image is being used as an alpha map */ + pixman_bool_t have_clip_region; /* FALSE if there is no clip */ + pixman_bool_t client_clip; /* Whether the source clip was + set by a client */ + pixman_bool_t clip_sources; /* Whether the clip applies when + * the image is used as a source + */ + pixman_bool_t dirty; + pixman_transform_t * transform; + pixman_repeat_t repeat; + pixman_filter_t filter; + pixman_fixed_t * filter_params; + int n_filter_params; + bits_image_t * alpha_map; + int alpha_origin_x; + int alpha_origin_y; + pixman_bool_t component_alpha; + property_changed_func_t property_changed; + + pixman_image_destroy_func_t destroy_func; + void * destroy_data; + + uint32_t flags; + pixman_format_code_t extended_format_code; +}; + +struct solid_fill +{ + image_common_t common; + pixman_color_t color; + + uint32_t color_32; + uint64_t color_64; +}; + +struct gradient +{ + image_common_t common; + int n_stops; + pixman_gradient_stop_t *stops; +}; + +struct linear_gradient +{ + gradient_t common; + pixman_point_fixed_t p1; + pixman_point_fixed_t p2; +}; + +struct circle +{ + pixman_fixed_t x; + pixman_fixed_t y; + pixman_fixed_t radius; +}; + +struct radial_gradient +{ + gradient_t common; + + circle_t c1; + circle_t c2; + + circle_t delta; + double a; + double inva; + double mindr; +}; + +struct conical_gradient +{ + gradient_t common; + pixman_point_fixed_t center; + double angle; +}; + +struct bits_image +{ + image_common_t common; + pixman_format_code_t format; + const pixman_indexed_t * indexed; + int width; + int height; + uint32_t * bits; + uint32_t * free_me; + int rowstride; /* in number of uint32_t's */ + + fetch_scanline_t get_scanline_32; + fetch_scanline_t get_scanline_64; + + fetch_scanline_t fetch_scanline_32; + fetch_pixel_32_t fetch_pixel_32; + store_scanline_t store_scanline_32; + + fetch_scanline_t fetch_scanline_64; + fetch_pixel_64_t fetch_pixel_64; + store_scanline_t store_scanline_64; + + /* Used for indirect access to the bits */ + pixman_read_memory_func_t read_func; + pixman_write_memory_func_t write_func; +}; + +union pixman_image +{ + image_type_t type; + image_common_t common; + bits_image_t bits; + gradient_t gradient; + linear_gradient_t linear; + conical_gradient_t conical; + radial_gradient_t radial; + solid_fill_t solid; +}; + +typedef struct pixman_iter_t pixman_iter_t; +typedef enum +{ + ITER_NARROW = (1 << 0), + + /* "Localized alpha" is when the alpha channel is used only to compute + * the alpha value of the destination. This means that the computation + * of the RGB values of the result is independent of the alpha value. + * + * For example, the OVER operator has localized alpha for the + * destination, because the RGB values of the result can be computed + * without knowing the destination alpha. Similarly, ADD has localized + * alpha for both source and destination because the RGB values of the + * result can be computed without knowing the alpha value of source or + * destination. + * + * When he destination is xRGB, this is useful knowledge, because then + * we can treat it as if it were ARGB, which means in some cases we can + * avoid copying it to a temporary buffer. + */ + ITER_LOCALIZED_ALPHA = (1 << 1), + ITER_IGNORE_ALPHA = (1 << 2), + ITER_IGNORE_RGB = (1 << 3) +} iter_flags_t; + +struct pixman_iter_t +{ + uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask); + void (* write_back) (pixman_iter_t *iter); + + pixman_image_t * image; + uint32_t * buffer; + int x, y; + int width; +}; + +void +_pixman_bits_image_setup_accessors (bits_image_t *image); + +void +_pixman_bits_image_src_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); +void +_pixman_bits_image_dest_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void +_pixman_linear_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void +_pixman_radial_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void +_pixman_conical_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +pixman_image_t * +_pixman_image_allocate (void); + +pixman_bool_t +_pixman_init_gradient (gradient_t * gradient, + const pixman_gradient_stop_t *stops, + int n_stops); +void +_pixman_image_reset_clip_region (pixman_image_t *image); + +void +_pixman_image_validate (pixman_image_t *image); + +#define PIXMAN_IMAGE_GET_LINE(image, x, y, type, out_stride, line, mul) \ + do \ + { \ + uint32_t *__bits__; \ + int __stride__; \ + \ + __bits__ = image->bits.bits; \ + __stride__ = image->bits.rowstride; \ + (out_stride) = \ + __stride__ * (int) sizeof (uint32_t) / (int) sizeof (type); \ + (line) = \ + ((type *) __bits__) + (out_stride) * (y) + (mul) * (x); \ + } while (0) + +/* + * Gradient walker + */ +typedef struct +{ + uint32_t left_ag; + uint32_t left_rb; + uint32_t right_ag; + uint32_t right_rb; + int32_t left_x; + int32_t right_x; + int32_t stepper; + + pixman_gradient_stop_t *stops; + int num_stops; + unsigned int spread; + + int need_reset; +} pixman_gradient_walker_t; + +void +_pixman_gradient_walker_init (pixman_gradient_walker_t *walker, + gradient_t * gradient, + unsigned int spread); + +void +_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker, + pixman_fixed_32_32_t pos); + +uint32_t +_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, + pixman_fixed_32_32_t x); + +/* + * Edges + */ + +#define MAX_ALPHA(n) ((1 << (n)) - 1) +#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) +#define N_X_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) + 1) + +#define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC (n)) +#define STEP_Y_BIG(n) (pixman_fixed_1 - (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n)) + +#define Y_FRAC_FIRST(n) (STEP_Y_BIG (n) / 2) +#define Y_FRAC_LAST(n) (Y_FRAC_FIRST (n) + (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n)) + +#define STEP_X_SMALL(n) (pixman_fixed_1 / N_X_FRAC (n)) +#define STEP_X_BIG(n) (pixman_fixed_1 - (N_X_FRAC (n) - 1) * STEP_X_SMALL (n)) + +#define X_FRAC_FIRST(n) (STEP_X_BIG (n) / 2) +#define X_FRAC_LAST(n) (X_FRAC_FIRST (n) + (N_X_FRAC (n) - 1) * STEP_X_SMALL (n)) + +#define RENDER_SAMPLES_X(x, n) \ + ((n) == 1? 0 : (pixman_fixed_frac (x) + \ + X_FRAC_FIRST (n)) / STEP_X_SMALL (n)) + +void +pixman_rasterize_edges_accessors (pixman_image_t *image, + pixman_edge_t * l, + pixman_edge_t * r, + pixman_fixed_t t, + pixman_fixed_t b); + +/* + * Implementations + */ +typedef struct pixman_implementation_t pixman_implementation_t; + +typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width); + +typedef void (*pixman_combine_64_func_t) (pixman_implementation_t *imp, + pixman_op_t op, + uint64_t * dest, + const uint64_t * src, + const uint64_t * mask, + int width); + +typedef void (*pixman_composite_func_t) (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src, + pixman_image_t * mask, + pixman_image_t * dest, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height); +typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height); +typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor); +typedef void (*pixman_iter_init_func_t) (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags); + +void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); +void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp); + +typedef struct +{ + pixman_op_t op; + pixman_format_code_t src_format; + uint32_t src_flags; + pixman_format_code_t mask_format; + uint32_t mask_flags; + pixman_format_code_t dest_format; + uint32_t dest_flags; + pixman_composite_func_t func; +} pixman_fast_path_t; + +struct pixman_implementation_t +{ + pixman_implementation_t * toplevel; + pixman_implementation_t * delegate; + const pixman_fast_path_t * fast_paths; + + pixman_blt_func_t blt; + pixman_fill_func_t fill; + pixman_iter_init_func_t src_iter_init; + pixman_iter_init_func_t dest_iter_init; + + pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS]; + pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS]; + pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS]; + pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS]; +}; + +uint32_t +_pixman_image_get_solid (pixman_implementation_t *imp, + pixman_image_t * image, + pixman_format_code_t format); + +pixman_implementation_t * +_pixman_implementation_create (pixman_implementation_t *delegate, + const pixman_fast_path_t *fast_paths); + +void +_pixman_implementation_combine_32 (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width); +void +_pixman_implementation_combine_64 (pixman_implementation_t *imp, + pixman_op_t op, + uint64_t * dest, + const uint64_t * src, + const uint64_t * mask, + int width); +void +_pixman_implementation_combine_32_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width); +void +_pixman_implementation_combine_64_ca (pixman_implementation_t *imp, + pixman_op_t op, + uint64_t * dest, + const uint64_t * src, + const uint64_t * mask, + int width); + +pixman_bool_t +_pixman_implementation_blt (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height); + +pixman_bool_t +_pixman_implementation_fill (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor); + +void +_pixman_implementation_src_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags); + +void +_pixman_implementation_dest_iter_init (pixman_implementation_t *imp, + pixman_iter_t *iter, + pixman_image_t *image, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags); + +/* Specific implementations */ +pixman_implementation_t * +_pixman_implementation_create_general (void); + +pixman_implementation_t * +_pixman_implementation_create_fast_path (void); + +#ifdef USE_MMX +pixman_implementation_t * +_pixman_implementation_create_mmx (void); +#endif + +#ifdef USE_SSE2 +pixman_implementation_t * +_pixman_implementation_create_sse2 (void); +#endif + +#ifdef USE_ARM_SIMD +pixman_implementation_t * +_pixman_implementation_create_arm_simd (void); +#endif + +#ifdef USE_ARM_NEON +pixman_implementation_t * +_pixman_implementation_create_arm_neon (void); +#endif + +#ifdef USE_VMX +pixman_implementation_t * +_pixman_implementation_create_vmx (void); +#endif + +pixman_implementation_t * +_pixman_choose_implementation (void); + + + +/* + * Utilities + */ +uint32_t * +_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask); + +/* These "formats" all have depth 0, so they + * will never clash with any real ones + */ +#define PIXMAN_null PIXMAN_FORMAT (0, 0, 0, 0, 0, 0) +#define PIXMAN_solid PIXMAN_FORMAT (0, 1, 0, 0, 0, 0) +#define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0) +#define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0) +#define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0) +#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0) + +#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1) + +#define FAST_PATH_ID_TRANSFORM (1 << 0) +#define FAST_PATH_NO_ALPHA_MAP (1 << 1) +#define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2) +#define FAST_PATH_NO_PAD_REPEAT (1 << 3) +#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4) +#define FAST_PATH_NO_ACCESSORS (1 << 5) +#define FAST_PATH_NARROW_FORMAT (1 << 6) +#define FAST_PATH_COMPONENT_ALPHA (1 << 8) +#define FAST_PATH_SAMPLES_OPAQUE (1 << 7) +#define FAST_PATH_UNIFIED_ALPHA (1 << 9) +#define FAST_PATH_SCALE_TRANSFORM (1 << 10) +#define FAST_PATH_NEAREST_FILTER (1 << 11) +#define FAST_PATH_HAS_TRANSFORM (1 << 12) +#define FAST_PATH_IS_OPAQUE (1 << 13) +#define FAST_PATH_NO_NORMAL_REPEAT (1 << 14) +#define FAST_PATH_NO_NONE_REPEAT (1 << 15) +#define FAST_PATH_SAMPLES_COVER_CLIP (1 << 16) +#define FAST_PATH_X_UNIT_POSITIVE (1 << 17) +#define FAST_PATH_AFFINE_TRANSFORM (1 << 18) +#define FAST_PATH_Y_UNIT_ZERO (1 << 19) +#define FAST_PATH_BILINEAR_FILTER (1 << 20) + +#define FAST_PATH_PAD_REPEAT \ + (FAST_PATH_NO_NONE_REPEAT | \ + FAST_PATH_NO_NORMAL_REPEAT | \ + FAST_PATH_NO_REFLECT_REPEAT) + +#define FAST_PATH_NORMAL_REPEAT \ + (FAST_PATH_NO_NONE_REPEAT | \ + FAST_PATH_NO_PAD_REPEAT | \ + FAST_PATH_NO_REFLECT_REPEAT) + +#define FAST_PATH_NONE_REPEAT \ + (FAST_PATH_NO_NORMAL_REPEAT | \ + FAST_PATH_NO_PAD_REPEAT | \ + FAST_PATH_NO_REFLECT_REPEAT) + +#define FAST_PATH_REFLECT_REPEAT \ + (FAST_PATH_NO_NONE_REPEAT | \ + FAST_PATH_NO_NORMAL_REPEAT | \ + FAST_PATH_NO_PAD_REPEAT) + +#define FAST_PATH_STANDARD_FLAGS \ + (FAST_PATH_NO_CONVOLUTION_FILTER | \ + FAST_PATH_NO_ACCESSORS | \ + FAST_PATH_NO_ALPHA_MAP | \ + FAST_PATH_NARROW_FORMAT) + +#define FAST_PATH_STD_DEST_FLAGS \ + (FAST_PATH_NO_ACCESSORS | \ + FAST_PATH_NO_ALPHA_MAP | \ + FAST_PATH_NARROW_FORMAT) + +#define SOURCE_FLAGS(format) \ + (FAST_PATH_STANDARD_FLAGS | \ + ((PIXMAN_ ## format == PIXMAN_solid) ? \ + 0 : (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_ID_TRANSFORM))) + +#define MASK_FLAGS(format, extra) \ + ((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra)) + +#define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \ + PIXMAN_OP_ ## op, \ + PIXMAN_ ## src, \ + src_flags, \ + PIXMAN_ ## mask, \ + mask_flags, \ + PIXMAN_ ## dest, \ + dest_flags, \ + func + +#define PIXMAN_STD_FAST_PATH(op, src, mask, dest, func) \ + { FAST_PATH ( \ + op, \ + src, SOURCE_FLAGS (src), \ + mask, MASK_FLAGS (mask, FAST_PATH_UNIFIED_ALPHA), \ + dest, FAST_PATH_STD_DEST_FLAGS, \ + func) } + +#define PIXMAN_STD_FAST_PATH_CA(op, src, mask, dest, func) \ + { FAST_PATH ( \ + op, \ + src, SOURCE_FLAGS (src), \ + mask, MASK_FLAGS (mask, FAST_PATH_COMPONENT_ALPHA), \ + dest, FAST_PATH_STD_DEST_FLAGS, \ + func) } + +/* Memory allocation helpers */ +void * +pixman_malloc_ab (unsigned int n, unsigned int b); + +void * +pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c); + +pixman_bool_t +pixman_multiply_overflows_int (unsigned int a, unsigned int b); + +pixman_bool_t +pixman_addition_overflows_int (unsigned int a, unsigned int b); + +/* Compositing utilities */ +void +pixman_expand (uint64_t * dst, + const uint32_t * src, + pixman_format_code_t format, + int width); + +void +pixman_contract (uint32_t * dst, + const uint64_t *src, + int width); + + +/* Region Helpers */ +pixman_bool_t +pixman_region32_copy_from_region16 (pixman_region32_t *dst, + pixman_region16_t *src); + +pixman_bool_t +pixman_region16_copy_from_region32 (pixman_region16_t *dst, + pixman_region32_t *src); + + +/* Misc macros */ + +#ifndef FALSE +# define FALSE 0 +#endif + +#ifndef TRUE +# define TRUE 1 +#endif + +#ifndef MIN +# define MIN(a, b) ((a < b) ? a : b) +#endif + +#ifndef MAX +# define MAX(a, b) ((a > b) ? a : b) +#endif + +/* Integer division that rounds towards -infinity */ +#define DIV(a, b) \ + ((((a) < 0) == ((b) < 0)) ? (a) / (b) : \ + ((a) - (b) + 1 - (((b) < 0) << 1)) / (b)) + +/* Modulus that produces the remainder wrt. DIV */ +#define MOD(a, b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b)) + +#define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v))) + +/* Conversion between 8888 and 0565 */ + +#define CONVERT_8888_TO_0565(s) \ + ((((s) >> 3) & 0x001f) | \ + (((s) >> 5) & 0x07e0) | \ + (((s) >> 8) & 0xf800)) + +#define CONVERT_0565_TO_0888(s) \ + (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ + ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ + ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) + +#define CONVERT_0565_TO_8888(s) (CONVERT_0565_TO_0888(s) | 0xff000000) + +/* Trivial versions that are useful in macros */ +#define CONVERT_8888_TO_8888(s) (s) +#define CONVERT_0565_TO_0565(s) (s) + +#define PIXMAN_FORMAT_IS_WIDE(f) \ + (PIXMAN_FORMAT_A (f) > 8 || \ + PIXMAN_FORMAT_R (f) > 8 || \ + PIXMAN_FORMAT_G (f) > 8 || \ + PIXMAN_FORMAT_B (f) > 8) + +#ifdef WORDS_BIGENDIAN +# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n)) +# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n)) +#else +# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n)) +# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n)) +#endif + +/* + * Various debugging code + */ + +#undef DEBUG + +#define COMPILE_TIME_ASSERT(x) \ + do { typedef int compile_time_assertion [(x)?1:-1]; } while (0) + +/* Turn on debugging depending on what type of release this is + */ +#if (((PIXMAN_VERSION_MICRO % 2) == 0) && ((PIXMAN_VERSION_MINOR % 2) == 1)) + +/* Debugging gets turned on for development releases because these + * are the things that end up in bleeding edge distributions such + * as Rawhide etc. + * + * For performance reasons we don't turn it on for stable releases or + * random git checkouts. (Random git checkouts are often used for + * performance work). + */ + +# define DEBUG + +#endif + +#ifdef DEBUG + +void +_pixman_log_error (const char *function, const char *message); + +#define return_if_fail(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + _pixman_log_error (FUNC, "The expression " # expr " was false"); \ + return; \ + } \ + } \ + while (0) + +#define return_val_if_fail(expr, retval) \ + do \ + { \ + if (!(expr)) \ + { \ + _pixman_log_error (FUNC, "The expression " # expr " was false"); \ + return (retval); \ + } \ + } \ + while (0) + +#define critical_if_fail(expr) \ + do \ + { \ + if (!(expr)) \ + _pixman_log_error (FUNC, "The expression " # expr " was false"); \ + } \ + while (0) + + +#else + +#define _pixman_log_error(f,m) do { } while (0) \ + +#define return_if_fail(expr) \ + do \ + { \ + if (!(expr)) \ + return; \ + } \ + while (0) + +#define return_val_if_fail(expr, retval) \ + do \ + { \ + if (!(expr)) \ + return (retval); \ + } \ + while (0) + +#define critical_if_fail(expr) \ + do \ + { \ + } \ + while (0) +#endif + +/* + * Timers + */ + +#ifdef PIXMAN_TIMERS + +static inline uint64_t +oil_profile_stamp_rdtsc (void) +{ + uint64_t ts; + + __asm__ __volatile__ ("rdtsc\n" : "=A" (ts)); + return ts; +} + +#define OIL_STAMP oil_profile_stamp_rdtsc + +typedef struct pixman_timer_t pixman_timer_t; + +struct pixman_timer_t +{ + int initialized; + const char * name; + uint64_t n_times; + uint64_t total; + pixman_timer_t *next; +}; + +extern int timer_defined; + +void pixman_timer_register (pixman_timer_t *timer); + +#define TIMER_BEGIN(tname) \ + { \ + static pixman_timer_t timer ## tname; \ + uint64_t begin ## tname; \ + \ + if (!timer ## tname.initialized) \ + { \ + timer ## tname.initialized = 1; \ + timer ## tname.name = # tname; \ + pixman_timer_register (&timer ## tname); \ + } \ + \ + timer ## tname.n_times++; \ + begin ## tname = OIL_STAMP (); + +#define TIMER_END(tname) \ + timer ## tname.total += OIL_STAMP () - begin ## tname; \ + } + +#endif /* PIXMAN_TIMERS */ + +#endif /* PIXMAN_PRIVATE_H */ diff --git a/pixman/pixman/pixman-radial-gradient.c b/pixman/pixman/pixman-radial-gradient.c index 97c151865..6523b8259 100644 --- a/pixman/pixman/pixman-radial-gradient.c +++ b/pixman/pixman/pixman-radial-gradient.c @@ -1,447 +1,463 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
-/*
- *
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- * Copyright © 2000 SuSE, Inc.
- * 2005 Lars Knoll & Zack Rusin, Trolltech
- * Copyright © 2007 Red Hat, Inc.
- *
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdlib.h>
-#include <math.h>
-#include "pixman-private.h"
-
-static inline pixman_fixed_32_32_t
-dot (pixman_fixed_48_16_t x1,
- pixman_fixed_48_16_t y1,
- pixman_fixed_48_16_t z1,
- pixman_fixed_48_16_t x2,
- pixman_fixed_48_16_t y2,
- pixman_fixed_48_16_t z2)
-{
- /*
- * Exact computation, assuming that the input values can
- * be represented as pixman_fixed_16_16_t
- */
- return x1 * x2 + y1 * y2 + z1 * z2;
-}
-
-static inline double
-fdot (double x1,
- double y1,
- double z1,
- double x2,
- double y2,
- double z2)
-{
- /*
- * Error can be unbound in some special cases.
- * Using clever dot product algorithms (for example compensated
- * dot product) would improve this but make the code much less
- * obvious
- */
- return x1 * x2 + y1 * y2 + z1 * z2;
-}
-
-static uint32_t
-radial_compute_color (double a,
- double b,
- double c,
- double inva,
- double dr,
- double mindr,
- pixman_gradient_walker_t *walker,
- pixman_repeat_t repeat)
-{
- /*
- * In this function error propagation can lead to bad results:
- * - det can have an unbound error (if b*b-a*c is very small),
- * potentially making it the opposite sign of what it should have been
- * (thus clearing a pixel that would have been colored or vice-versa)
- * or propagating the error to sqrtdet;
- * if det has the wrong sign or b is very small, this can lead to bad
- * results
- *
- * - the algorithm used to compute the solutions of the quadratic
- * equation is not numerically stable (but saves one division compared
- * to the numerically stable one);
- * this can be a problem if a*c is much smaller than b*b
- *
- * - the above problems are worse if a is small (as inva becomes bigger)
- */
- double det;
-
- if (a == 0)
- {
- double t;
-
- if (b == 0)
- return 0;
-
- t = pixman_fixed_1 / 2 * c / b;
- if (repeat == PIXMAN_REPEAT_NONE)
- {
- if (0 <= t && t <= pixman_fixed_1)
- return _pixman_gradient_walker_pixel (walker, t);
- }
- else
- {
- if (t * dr > mindr)
- return _pixman_gradient_walker_pixel (walker, t);
- }
-
- return 0;
- }
-
- det = fdot (b, a, 0, b, -c, 0);
- if (det >= 0)
- {
- double sqrtdet, t0, t1;
-
- sqrtdet = sqrt (det);
- t0 = (b + sqrtdet) * inva;
- t1 = (b - sqrtdet) * inva;
-
- if (repeat == PIXMAN_REPEAT_NONE)
- {
- if (0 <= t0 && t0 <= pixman_fixed_1)
- return _pixman_gradient_walker_pixel (walker, t0);
- else if (0 <= t1 && t1 <= pixman_fixed_1)
- return _pixman_gradient_walker_pixel (walker, t1);
- }
- else
- {
- if (t0 * dr > mindr)
- return _pixman_gradient_walker_pixel (walker, t0);
- else if (t1 * dr > mindr)
- return _pixman_gradient_walker_pixel (walker, t1);
- }
- }
-
- return 0;
-}
-
-static void
-radial_gradient_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- /*
- * Implementation of radial gradients following the PDF specification.
- * See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference
- * Manual (PDF 32000-1:2008 at the time of this writing).
- *
- * In the radial gradient problem we are given two circles (c₁,r₁) and
- * (c₂,r₂) that define the gradient itself.
- *
- * Mathematically the gradient can be defined as the family of circles
- *
- * ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂)
- *
- * excluding those circles whose radius would be < 0. When a point
- * belongs to more than one circle, the one with a bigger t is the only
- * one that contributes to its color. When a point does not belong
- * to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0).
- * Further limitations on the range of values for t are imposed when
- * the gradient is not repeated, namely t must belong to [0,1].
- *
- * The graphical result is the same as drawing the valid (radius > 0)
- * circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient
- * is not repeated) using SOURCE operatior composition.
- *
- * It looks like a cone pointing towards the viewer if the ending circle
- * is smaller than the starting one, a cone pointing inside the page if
- * the starting circle is the smaller one and like a cylinder if they
- * have the same radius.
- *
- * What we actually do is, given the point whose color we are interested
- * in, compute the t values for that point, solving for t in:
- *
- * length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂
- *
- * Let's rewrite it in a simpler way, by defining some auxiliary
- * variables:
- *
- * cd = c₂ - c₁
- * pd = p - c₁
- * dr = r₂ - r₁
- * lenght(t·cd - pd) = r₁ + t·dr
- *
- * which actually means
- *
- * hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr
- *
- * or
- *
- * ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr.
- *
- * If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes:
- *
- * (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)²
- *
- * where we can actually expand the squares and solve for t:
- *
- * t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² =
- * = r₁² + 2·r₁·t·dr + t²·dr²
- *
- * (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t +
- * (pdx² + pdy² - r₁²) = 0
- *
- * A = cdx² + cdy² - dr²
- * B = pdx·cdx + pdy·cdy + r₁·dr
- * C = pdx² + pdy² - r₁²
- * At² - 2Bt + C = 0
- *
- * The solutions (unless the equation degenerates because of A = 0) are:
- *
- * t = (B ± ⎷(B² - A·C)) / A
- *
- * The solution we are going to prefer is the bigger one, unless the
- * radius associated to it is negative (or it falls outside the valid t
- * range).
- *
- * Additional observations (useful for optimizations):
- * A does not depend on p
- *
- * A < 0 <=> one of the two circles completely contains the other one
- * <=> for every p, the radiuses associated with the two t solutions
- * have opposite sign
- */
-
- gradient_t *gradient = (gradient_t *)image;
- radial_gradient_t *radial = (radial_gradient_t *)image;
- uint32_t *end = buffer + width;
- pixman_gradient_walker_t walker;
- pixman_vector_t v, unit;
-
- /* reference point is the center of the pixel */
- v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
- v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
- v.vector[2] = pixman_fixed_1;
-
- _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
-
- if (image->common.transform)
- {
- if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
-
- unit.vector[0] = image->common.transform->matrix[0][0];
- unit.vector[1] = image->common.transform->matrix[1][0];
- unit.vector[2] = image->common.transform->matrix[2][0];
- }
- else
- {
- unit.vector[0] = pixman_fixed_1;
- unit.vector[1] = 0;
- unit.vector[2] = 0;
- }
-
- if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)
- {
- /*
- * Given:
- *
- * t = (B ± ⎷(B² - A·C)) / A
- *
- * where
- *
- * A = cdx² + cdy² - dr²
- * B = pdx·cdx + pdy·cdy + r₁·dr
- * C = pdx² + pdy² - r₁²
- * det = B² - A·C
- *
- * Since we have an affine transformation, we know that (pdx, pdy)
- * increase linearly with each pixel,
- *
- * pdx = pdx₀ + n·ux,
- * pdy = pdy₀ + n·uy,
- *
- * we can then express B, C and det through multiple differentiation.
- */
- pixman_fixed_32_32_t b, db, c, dc, ddc;
-
- /* warning: this computation may overflow */
- v.vector[0] -= radial->c1.x;
- v.vector[1] -= radial->c1.y;
-
- /*
- * B and C are computed and updated exactly.
- * If fdot was used instead of dot, in the worst case it would
- * lose 11 bits of precision in each of the multiplication and
- * summing up would zero out all the bit that were preserved,
- * thus making the result 0 instead of the correct one.
- * This would mean a worst case of unbound relative error or
- * about 2^10 absolute error
- */
- b = dot (v.vector[0], v.vector[1], radial->c1.radius,
- radial->delta.x, radial->delta.y, radial->delta.radius);
- db = dot (unit.vector[0], unit.vector[1], 0,
- radial->delta.x, radial->delta.y, 0);
-
- c = dot (v.vector[0], v.vector[1],
- -((pixman_fixed_48_16_t) radial->c1.radius),
- v.vector[0], v.vector[1], radial->c1.radius);
- dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0],
- 2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1],
- 0,
- unit.vector[0], unit.vector[1], 0);
- ddc = 2 * dot (unit.vector[0], unit.vector[1], 0,
- unit.vector[0], unit.vector[1], 0);
-
- while (buffer < end)
- {
- if (!mask || *mask++)
- {
- *buffer = radial_compute_color (radial->a, b, c,
- radial->inva,
- radial->delta.radius,
- radial->mindr,
- &walker,
- image->common.repeat);
- }
-
- b += db;
- c += dc;
- dc += ddc;
- ++buffer;
- }
- }
- else
- {
- /* projective */
- /* Warning:
- * error propagation guarantees are much looser than in the affine case
- */
- while (buffer < end)
- {
- if (!mask || *mask++)
- {
- if (v.vector[2] != 0)
- {
- double pdx, pdy, invv2, b, c;
-
- invv2 = 1. * pixman_fixed_1 / v.vector[2];
-
- pdx = v.vector[0] * invv2 - radial->c1.x;
- /* / pixman_fixed_1 */
-
- pdy = v.vector[1] * invv2 - radial->c1.y;
- /* / pixman_fixed_1 */
-
- b = fdot (pdx, pdy, radial->c1.radius,
- radial->delta.x, radial->delta.y,
- radial->delta.radius);
- /* / pixman_fixed_1 / pixman_fixed_1 */
-
- c = fdot (pdx, pdy, -radial->c1.radius,
- pdx, pdy, radial->c1.radius);
- /* / pixman_fixed_1 / pixman_fixed_1 */
-
- *buffer = radial_compute_color (radial->a, b, c,
- radial->inva,
- radial->delta.radius,
- radial->mindr,
- &walker,
- image->common.repeat);
- }
- else
- {
- *buffer = 0;
- }
- }
-
- ++buffer;
-
- v.vector[0] += unit.vector[0];
- v.vector[1] += unit.vector[1];
- v.vector[2] += unit.vector[2];
- }
- }
-}
-
-static void
-radial_gradient_property_changed (pixman_image_t *image)
-{
- image->common.get_scanline_32 = radial_gradient_get_scanline_32;
- image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-}
-
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_radial_gradient (pixman_point_fixed_t * inner,
- pixman_point_fixed_t * outer,
- pixman_fixed_t inner_radius,
- pixman_fixed_t outer_radius,
- const pixman_gradient_stop_t *stops,
- int n_stops)
-{
- pixman_image_t *image;
- radial_gradient_t *radial;
-
- image = _pixman_image_allocate ();
-
- if (!image)
- return NULL;
-
- radial = &image->radial;
-
- if (!_pixman_init_gradient (&radial->common, stops, n_stops))
- {
- free (image);
- return NULL;
- }
-
- image->type = RADIAL;
-
- radial->c1.x = inner->x;
- radial->c1.y = inner->y;
- radial->c1.radius = inner_radius;
- radial->c2.x = outer->x;
- radial->c2.y = outer->y;
- radial->c2.radius = outer_radius;
-
- /* warning: this computations may overflow */
- radial->delta.x = radial->c2.x - radial->c1.x;
- radial->delta.y = radial->c2.y - radial->c1.y;
- radial->delta.radius = radial->c2.radius - radial->c1.radius;
-
- /* computed exactly, then cast to double -> every bit of the double
- representation is correct (53 bits) */
- radial->a = dot (radial->delta.x, radial->delta.y, -radial->delta.radius,
- radial->delta.x, radial->delta.y, radial->delta.radius);
- if (radial->a != 0)
- radial->inva = 1. * pixman_fixed_1 / radial->a;
-
- radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius;
-
- image->common.property_changed = radial_gradient_property_changed;
-
- return image;
-}
-
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ +/* + * + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. + * Copyright © 2000 SuSE, Inc. + * 2005 Lars Knoll & Zack Rusin, Trolltech + * Copyright © 2007 Red Hat, Inc. + * + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdlib.h> +#include <math.h> +#include "pixman-private.h" + +static inline pixman_fixed_32_32_t +dot (pixman_fixed_48_16_t x1, + pixman_fixed_48_16_t y1, + pixman_fixed_48_16_t z1, + pixman_fixed_48_16_t x2, + pixman_fixed_48_16_t y2, + pixman_fixed_48_16_t z2) +{ + /* + * Exact computation, assuming that the input values can + * be represented as pixman_fixed_16_16_t + */ + return x1 * x2 + y1 * y2 + z1 * z2; +} + +static inline double +fdot (double x1, + double y1, + double z1, + double x2, + double y2, + double z2) +{ + /* + * Error can be unbound in some special cases. + * Using clever dot product algorithms (for example compensated + * dot product) would improve this but make the code much less + * obvious + */ + return x1 * x2 + y1 * y2 + z1 * z2; +} + +static uint32_t +radial_compute_color (double a, + double b, + double c, + double inva, + double dr, + double mindr, + pixman_gradient_walker_t *walker, + pixman_repeat_t repeat) +{ + /* + * In this function error propagation can lead to bad results: + * - det can have an unbound error (if b*b-a*c is very small), + * potentially making it the opposite sign of what it should have been + * (thus clearing a pixel that would have been colored or vice-versa) + * or propagating the error to sqrtdet; + * if det has the wrong sign or b is very small, this can lead to bad + * results + * + * - the algorithm used to compute the solutions of the quadratic + * equation is not numerically stable (but saves one division compared + * to the numerically stable one); + * this can be a problem if a*c is much smaller than b*b + * + * - the above problems are worse if a is small (as inva becomes bigger) + */ + double det; + + if (a == 0) + { + double t; + + if (b == 0) + return 0; + + t = pixman_fixed_1 / 2 * c / b; + if (repeat == PIXMAN_REPEAT_NONE) + { + if (0 <= t && t <= pixman_fixed_1) + return _pixman_gradient_walker_pixel (walker, t); + } + else + { + if (t * dr > mindr) + return _pixman_gradient_walker_pixel (walker, t); + } + + return 0; + } + + det = fdot (b, a, 0, b, -c, 0); + if (det >= 0) + { + double sqrtdet, t0, t1; + + sqrtdet = sqrt (det); + t0 = (b + sqrtdet) * inva; + t1 = (b - sqrtdet) * inva; + + if (repeat == PIXMAN_REPEAT_NONE) + { + if (0 <= t0 && t0 <= pixman_fixed_1) + return _pixman_gradient_walker_pixel (walker, t0); + else if (0 <= t1 && t1 <= pixman_fixed_1) + return _pixman_gradient_walker_pixel (walker, t1); + } + else + { + if (t0 * dr > mindr) + return _pixman_gradient_walker_pixel (walker, t0); + else if (t1 * dr > mindr) + return _pixman_gradient_walker_pixel (walker, t1); + } + } + + return 0; +} + +static uint32_t * +radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + /* + * Implementation of radial gradients following the PDF specification. + * See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference + * Manual (PDF 32000-1:2008 at the time of this writing). + * + * In the radial gradient problem we are given two circles (c₁,r₁) and + * (c₂,r₂) that define the gradient itself. + * + * Mathematically the gradient can be defined as the family of circles + * + * ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂) + * + * excluding those circles whose radius would be < 0. When a point + * belongs to more than one circle, the one with a bigger t is the only + * one that contributes to its color. When a point does not belong + * to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0). + * Further limitations on the range of values for t are imposed when + * the gradient is not repeated, namely t must belong to [0,1]. + * + * The graphical result is the same as drawing the valid (radius > 0) + * circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient + * is not repeated) using SOURCE operatior composition. + * + * It looks like a cone pointing towards the viewer if the ending circle + * is smaller than the starting one, a cone pointing inside the page if + * the starting circle is the smaller one and like a cylinder if they + * have the same radius. + * + * What we actually do is, given the point whose color we are interested + * in, compute the t values for that point, solving for t in: + * + * length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂ + * + * Let's rewrite it in a simpler way, by defining some auxiliary + * variables: + * + * cd = c₂ - c₁ + * pd = p - c₁ + * dr = r₂ - r₁ + * lenght(t·cd - pd) = r₁ + t·dr + * + * which actually means + * + * hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr + * + * or + * + * ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr. + * + * If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes: + * + * (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)² + * + * where we can actually expand the squares and solve for t: + * + * t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² = + * = r₁² + 2·r₁·t·dr + t²·dr² + * + * (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t + + * (pdx² + pdy² - r₁²) = 0 + * + * A = cdx² + cdy² - dr² + * B = pdx·cdx + pdy·cdy + r₁·dr + * C = pdx² + pdy² - r₁² + * At² - 2Bt + C = 0 + * + * The solutions (unless the equation degenerates because of A = 0) are: + * + * t = (B ± ⎷(B² - A·C)) / A + * + * The solution we are going to prefer is the bigger one, unless the + * radius associated to it is negative (or it falls outside the valid t + * range). + * + * Additional observations (useful for optimizations): + * A does not depend on p + * + * A < 0 <=> one of the two circles completely contains the other one + * <=> for every p, the radiuses associated with the two t solutions + * have opposite sign + */ + pixman_image_t *image = iter->image; + int x = iter->x; + int y = iter->y; + int width = iter->width; + uint32_t *buffer = iter->buffer; + + gradient_t *gradient = (gradient_t *)image; + radial_gradient_t *radial = (radial_gradient_t *)image; + uint32_t *end = buffer + width; + pixman_gradient_walker_t walker; + pixman_vector_t v, unit; + + /* reference point is the center of the pixel */ + v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; + v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; + v.vector[2] = pixman_fixed_1; + + _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); + + if (image->common.transform) + { + if (!pixman_transform_point_3d (image->common.transform, &v)) + return iter->buffer; + + unit.vector[0] = image->common.transform->matrix[0][0]; + unit.vector[1] = image->common.transform->matrix[1][0]; + unit.vector[2] = image->common.transform->matrix[2][0]; + } + else + { + unit.vector[0] = pixman_fixed_1; + unit.vector[1] = 0; + unit.vector[2] = 0; + } + + if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1) + { + /* + * Given: + * + * t = (B ± ⎷(B² - A·C)) / A + * + * where + * + * A = cdx² + cdy² - dr² + * B = pdx·cdx + pdy·cdy + r₁·dr + * C = pdx² + pdy² - r₁² + * det = B² - A·C + * + * Since we have an affine transformation, we know that (pdx, pdy) + * increase linearly with each pixel, + * + * pdx = pdx₀ + n·ux, + * pdy = pdy₀ + n·uy, + * + * we can then express B, C and det through multiple differentiation. + */ + pixman_fixed_32_32_t b, db, c, dc, ddc; + + /* warning: this computation may overflow */ + v.vector[0] -= radial->c1.x; + v.vector[1] -= radial->c1.y; + + /* + * B and C are computed and updated exactly. + * If fdot was used instead of dot, in the worst case it would + * lose 11 bits of precision in each of the multiplication and + * summing up would zero out all the bit that were preserved, + * thus making the result 0 instead of the correct one. + * This would mean a worst case of unbound relative error or + * about 2^10 absolute error + */ + b = dot (v.vector[0], v.vector[1], radial->c1.radius, + radial->delta.x, radial->delta.y, radial->delta.radius); + db = dot (unit.vector[0], unit.vector[1], 0, + radial->delta.x, radial->delta.y, 0); + + c = dot (v.vector[0], v.vector[1], + -((pixman_fixed_48_16_t) radial->c1.radius), + v.vector[0], v.vector[1], radial->c1.radius); + dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0], + 2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1], + 0, + unit.vector[0], unit.vector[1], 0); + ddc = 2 * dot (unit.vector[0], unit.vector[1], 0, + unit.vector[0], unit.vector[1], 0); + + while (buffer < end) + { + if (!mask || *mask++) + { + *buffer = radial_compute_color (radial->a, b, c, + radial->inva, + radial->delta.radius, + radial->mindr, + &walker, + image->common.repeat); + } + + b += db; + c += dc; + dc += ddc; + ++buffer; + } + } + else + { + /* projective */ + /* Warning: + * error propagation guarantees are much looser than in the affine case + */ + while (buffer < end) + { + if (!mask || *mask++) + { + if (v.vector[2] != 0) + { + double pdx, pdy, invv2, b, c; + + invv2 = 1. * pixman_fixed_1 / v.vector[2]; + + pdx = v.vector[0] * invv2 - radial->c1.x; + /* / pixman_fixed_1 */ + + pdy = v.vector[1] * invv2 - radial->c1.y; + /* / pixman_fixed_1 */ + + b = fdot (pdx, pdy, radial->c1.radius, + radial->delta.x, radial->delta.y, + radial->delta.radius); + /* / pixman_fixed_1 / pixman_fixed_1 */ + + c = fdot (pdx, pdy, -radial->c1.radius, + pdx, pdy, radial->c1.radius); + /* / pixman_fixed_1 / pixman_fixed_1 */ + + *buffer = radial_compute_color (radial->a, b, c, + radial->inva, + radial->delta.radius, + radial->mindr, + &walker, + image->common.repeat); + } + else + { + *buffer = 0; + } + } + + ++buffer; + + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } + + iter->y++; + return iter->buffer; +} + +static uint32_t * +radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); + + pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + + return buffer; +} + +void +_pixman_radial_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + iter->get_scanline = radial_get_scanline_narrow; + else + iter->get_scanline = radial_get_scanline_wide; +} + +PIXMAN_EXPORT pixman_image_t * +pixman_image_create_radial_gradient (pixman_point_fixed_t * inner, + pixman_point_fixed_t * outer, + pixman_fixed_t inner_radius, + pixman_fixed_t outer_radius, + const pixman_gradient_stop_t *stops, + int n_stops) +{ + pixman_image_t *image; + radial_gradient_t *radial; + + image = _pixman_image_allocate (); + + if (!image) + return NULL; + + radial = &image->radial; + + if (!_pixman_init_gradient (&radial->common, stops, n_stops)) + { + free (image); + return NULL; + } + + image->type = RADIAL; + + radial->c1.x = inner->x; + radial->c1.y = inner->y; + radial->c1.radius = inner_radius; + radial->c2.x = outer->x; + radial->c2.y = outer->y; + radial->c2.radius = outer_radius; + + /* warning: this computations may overflow */ + radial->delta.x = radial->c2.x - radial->c1.x; + radial->delta.y = radial->c2.y - radial->c1.y; + radial->delta.radius = radial->c2.radius - radial->c1.radius; + + /* computed exactly, then cast to double -> every bit of the double + representation is correct (53 bits) */ + radial->a = dot (radial->delta.x, radial->delta.y, -radial->delta.radius, + radial->delta.x, radial->delta.y, radial->delta.radius); + if (radial->a != 0) + radial->inva = 1. * pixman_fixed_1 / radial->a; + + radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius; + + return image; +} + diff --git a/pixman/pixman/pixman-solid-fill.c b/pixman/pixman/pixman-solid-fill.c index afff3c479..67681f2c0 100644 --- a/pixman/pixman/pixman-solid-fill.c +++ b/pixman/pixman/pixman-solid-fill.c @@ -1,117 +1,92 @@ -/*
- * Copyright © 2000 SuSE, Inc.
- * Copyright © 2007, 2009 Red Hat, Inc.
- * Copyright © 2009 Soren Sandmann
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "pixman-private.h"
-
-static void
-solid_fill_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- uint32_t *end = buffer + width;
- uint32_t color = image->solid.color_32;
-
- while (buffer < end)
- *(buffer++) = color;
-
- return;
-}
-
-static void
-solid_fill_get_scanline_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- uint64_t *b = (uint64_t *)buffer;
- uint64_t *e = b + width;
- uint64_t color = image->solid.color_64;
-
- while (b < e)
- *(b++) = color;
-}
-
-static source_image_class_t
-solid_fill_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height)
-{
- return SOURCE_IMAGE_CLASS_HORIZONTAL;
-}
-
-static void
-solid_fill_property_changed (pixman_image_t *image)
-{
- image->common.get_scanline_32 = solid_fill_get_scanline_32;
- image->common.get_scanline_64 = solid_fill_get_scanline_64;
-}
-
-static uint32_t
-color_to_uint32 (const pixman_color_t *color)
-{
- return
- (color->alpha >> 8 << 24) |
- (color->red >> 8 << 16) |
- (color->green & 0xff00) |
- (color->blue >> 8);
-}
-
-static uint64_t
-color_to_uint64 (const pixman_color_t *color)
-{
- return
- ((uint64_t)color->alpha << 48) |
- ((uint64_t)color->red << 32) |
- ((uint64_t)color->green << 16) |
- ((uint64_t)color->blue);
-}
-
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_solid_fill (pixman_color_t *color)
-{
- pixman_image_t *img = _pixman_image_allocate ();
-
- if (!img)
- return NULL;
-
- img->type = SOLID;
- img->solid.color = *color;
- img->solid.color_32 = color_to_uint32 (color);
- img->solid.color_64 = color_to_uint64 (color);
-
- img->common.classify = solid_fill_classify;
- img->common.property_changed = solid_fill_property_changed;
-
- return img;
-}
-
+/* + * Copyright © 2000 SuSE, Inc. + * Copyright © 2007, 2009 Red Hat, Inc. + * Copyright © 2009 Soren Sandmann + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "pixman-private.h" + +void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + { + uint32_t *b = (uint32_t *)buffer; + uint32_t *e = b + width; + uint32_t color = image->solid.color_32; + + while (b < e) + *(b++) = color; + } + else + { + uint64_t *b = (uint64_t *)buffer; + uint64_t *e = b + width; + uint64_t color = image->solid.color_64; + + while (b < e) + *(b++) = color; + } + + iter->get_scanline = _pixman_iter_get_scanline_noop; +} + +static uint32_t +color_to_uint32 (const pixman_color_t *color) +{ + return + (color->alpha >> 8 << 24) | + (color->red >> 8 << 16) | + (color->green & 0xff00) | + (color->blue >> 8); +} + +static uint64_t +color_to_uint64 (const pixman_color_t *color) +{ + return + ((uint64_t)color->alpha << 48) | + ((uint64_t)color->red << 32) | + ((uint64_t)color->green << 16) | + ((uint64_t)color->blue); +} + +PIXMAN_EXPORT pixman_image_t * +pixman_image_create_solid_fill (pixman_color_t *color) +{ + pixman_image_t *img = _pixman_image_allocate (); + + if (!img) + return NULL; + + img->type = SOLID; + img->solid.color = *color; + img->solid.color_32 = color_to_uint32 (color); + img->solid.color_64 = color_to_uint64 (color); + + return img; +} + diff --git a/pixman/pixman/pixman-sse2.c b/pixman/pixman/pixman-sse2.c index 94ba54cbf..3c0a42f41 100644 --- a/pixman/pixman/pixman-sse2.c +++ b/pixman/pixman/pixman-sse2.c @@ -2598,7 +2598,7 @@ sse2_composite_over_n_8888 (pixman_implementation_t *imp, __m128i xmm_src, xmm_alpha; __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); if (src == 0) return; @@ -2681,7 +2681,7 @@ sse2_composite_over_n_0565 (pixman_implementation_t *imp, __m128i xmm_src, xmm_alpha; __m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); if (src == 0) return; @@ -2776,7 +2776,7 @@ sse2_composite_add_n_8888_8888_ca (pixman_implementation_t *imp, __m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -2904,7 +2904,7 @@ sse2_composite_over_n_8888_8888_ca (pixman_implementation_t *imp, __m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); if (src == 0) return; @@ -3036,7 +3036,7 @@ sse2_composite_over_8888_n_8888 (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE ( src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - mask = _pixman_image_get_solid (mask_image, PIXMAN_a8r8g8b8); + mask = _pixman_image_get_solid (imp, mask_image, PIXMAN_a8r8g8b8); xmm_mask = create_mask_16_128 (mask >> 24); @@ -3226,7 +3226,7 @@ sse2_composite_over_x888_n_8888 (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE ( src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - mask = _pixman_image_get_solid (mask_image, PIXMAN_a8r8g8b8); + mask = _pixman_image_get_solid (imp, mask_image, PIXMAN_a8r8g8b8); xmm_mask = create_mask_16_128 (mask >> 24); xmm_alpha = mask_00ff; @@ -3498,7 +3498,7 @@ sse2_composite_over_n_8_8888 (pixman_implementation_t *imp, __m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -3782,7 +3782,7 @@ sse2_composite_src_n_8_8888 (pixman_implementation_t *imp, __m128i xmm_src, xmm_def; __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -3918,7 +3918,7 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t *imp, __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; __m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); srca = src >> 24; if (src == 0) @@ -4318,7 +4318,7 @@ sse2_composite_over_n_8888_0565_ca (pixman_implementation_t *imp, __m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); if (src == 0) return; @@ -4471,7 +4471,7 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE ( mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); sa = src >> 24; @@ -4570,7 +4570,7 @@ sse2_composite_in_n_8 (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE ( dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src)); @@ -4758,7 +4758,7 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE ( mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); sa = src >> 24; @@ -4855,7 +4855,7 @@ sse2_composite_add_n_8 (pixman_implementation_t *imp, PIXMAN_IMAGE_GET_LINE ( dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); src >>= 24; @@ -5480,7 +5480,7 @@ sse2_composite_over_reverse_n_8888 (pixman_implementation_t *imp, int dst_stride; int32_t w; - src = _pixman_image_get_solid (src_image, dst_image->bits.format); + src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format); if (src == 0) return; diff --git a/pixman/pixman/pixman-utils.c b/pixman/pixman/pixman-utils.c index 3ef88b753..cb4e62199 100644 --- a/pixman/pixman/pixman-utils.c +++ b/pixman/pixman/pixman-utils.c @@ -167,6 +167,12 @@ pixman_contract (uint32_t * dst, } } +uint32_t * +_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask) +{ + return iter->buffer; +} + #define N_TMP_BOXES (16) pixman_bool_t diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am index 71e535374..8d8471d1c 100644 --- a/pixman/test/Makefile.am +++ b/pixman/test/Makefile.am @@ -92,6 +92,7 @@ TESTPROGRAMS_GTK = \ clip-in \ composite-test \ gradient-test \ + radial-test \ alpha-test \ screen-test \ convolution-test \ @@ -102,6 +103,9 @@ INCLUDES += $(GTK_CFLAGS) gradient_test_LDADD = $(GTK_LDADD) gradient_test_SOURCES = gradient-test.c $(GTK_UTILS) +radial_test_LDADD = $(GTK_LDADD) +radial_test_SOURCES = radial-test.c utils.c utils.h $(GTK_UTILS) + alpha_test_LDADD = $(GTK_LDADD) alpha_test_SOURCES = alpha-test.c $(GTK_UTILS) diff --git a/pixman/test/alphamap.c b/pixman/test/alphamap.c index ba3130e5d..554b309fb 100644 --- a/pixman/test/alphamap.c +++ b/pixman/test/alphamap.c @@ -1,259 +1,256 @@ -#include <stdio.h>
-#include <stdlib.h>
-#include "utils.h"
-
-#define WIDTH 100
-#define HEIGHT 100
-
-static const pixman_format_code_t formats[] =
-{
- PIXMAN_a8r8g8b8,
- PIXMAN_a2r10g10b10,
- PIXMAN_a4r4g4b4,
- PIXMAN_a8
-};
-
-static const pixman_format_code_t alpha_formats[] =
-{
- PIXMAN_null,
- PIXMAN_a8,
- PIXMAN_a2r10g10b10,
- PIXMAN_a4r4g4b4
-};
-
-static const int origins[] =
-{
- 0, 10, -100
-};
-
-static const char *
-format_name (pixman_format_code_t format)
-{
- if (format == PIXMAN_a8)
- return "a8";
- else if (format == PIXMAN_a2r10g10b10)
- return "a2r10g10b10";
- else if (format == PIXMAN_a8r8g8b8)
- return "a8r8g8b8";
- else if (format == PIXMAN_a4r4g4b4)
- return "a4r4g4b4";
- else if (format == PIXMAN_null)
- return "none";
- else
- assert (0);
-
- return "<unknown - bug in alphamap.c>";
-}
-
-static void
-on_destroy (pixman_image_t *image, void *data)
-{
- uint32_t *bits = pixman_image_get_data (image);
-
- fence_free (bits);
-}
-
-static pixman_image_t *
-make_image (pixman_format_code_t format)
-{
- uint32_t *bits;
- uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
- pixman_image_t *image;
-
- bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
-
- image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
-
- if (image && bits)
- pixman_image_set_destroy_function (image, on_destroy, NULL);
-
- return image;
-}
-
-static pixman_image_t *
-create_image (pixman_format_code_t format, pixman_format_code_t alpha_format,
- int alpha_origin_x, int alpha_origin_y)
-{
- pixman_image_t *image = make_image (format);
-
- if (alpha_format != PIXMAN_null)
- {
- pixman_image_t *alpha = make_image (alpha_format);
-
- pixman_image_set_alpha_map (image, alpha,
- alpha_origin_x, alpha_origin_y);
- pixman_image_unref (alpha);
- }
-
- return image;
-}
-
-static uint8_t
-get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
-{
- uint8_t *bits;
- uint8_t r;
-
- if (image->common.alpha_map)
- {
- if (x - orig_x >= 0 && x - orig_x < WIDTH &&
- y - orig_y >= 0 && y - orig_y < HEIGHT)
- {
- image = (pixman_image_t *)image->common.alpha_map;
-
- x -= orig_x;
- y -= orig_y;
- }
- else
- {
- return 0;
- }
- }
-
- bits = (uint8_t *)image->bits.bits;
-
- if (image->bits.format == PIXMAN_a8)
- {
- r = bits[y * WIDTH + x];
- }
- else if (image->bits.format == PIXMAN_a2r10g10b10)
- {
- r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
- r |= r << 2;
- r |= r << 4;
- }
- else if (image->bits.format == PIXMAN_a8r8g8b8)
- {
- r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
- }
- else if (image->bits.format == PIXMAN_a4r4g4b4)
- {
- r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
- r |= r << 4;
- }
- else
- {
- assert (0);
- }
-
- return r;
-}
-
-#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
-
-static int
-run_test (int s, int d, int sa, int da, int soff, int doff)
-{
- pixman_format_code_t sf = formats[s];
- pixman_format_code_t df = formats[d];
- pixman_format_code_t saf = alpha_formats[sa];
- pixman_format_code_t daf = alpha_formats[da];
- pixman_image_t *src, *dst, *orig_dst;
- pixman_transform_t t1;
- int j, k;
- int n_alpha_bits;
-
- soff = origins[soff];
- doff = origins[doff];
-
- n_alpha_bits = PIXMAN_FORMAT_A (df);
- if (daf != PIXMAN_null)
- n_alpha_bits = PIXMAN_FORMAT_A (daf);
-
-
- src = create_image (sf, saf, soff, soff);
- orig_dst = create_image (df, daf, doff, doff);
- dst = create_image (df, daf, doff, doff);
-
- /* Transformations on destinations should be ignored, so just set some
- * random one.
- */
- pixman_transform_init_identity (&t1);
- pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11));
- pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11));
- pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17));
-
-#if 0
- /* Unfortunately, this is actually broken at the moment, so we can't
- * actually turn it on
- */
- pixman_image_set_transform (dst, &t1);
-#endif
-
- pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
- 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-
- pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst,
- 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-
- for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j)
- {
- for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k)
- {
- uint8_t sa, da, oda, ref;
-
- sa = get_alpha (src, k, j, soff, soff);
- da = get_alpha (dst, k, j, doff, doff);
- oda = get_alpha (orig_dst, k, j, doff, doff);
-
- if (sa + oda > 255)
- ref = 255;
- else
- ref = sa + oda;
-
- if (da >> (8 - n_alpha_bits) != ref >> (8 - n_alpha_bits))
- {
- printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
- k, j, ref, da, sa, oda);
-
- printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
- format_name (sf),
- format_name (saf),
- soff, soff,
- format_name (df),
- format_name (daf),
- doff, doff);
- return 1;
- }
- }
- }
-
- pixman_image_set_alpha_map (src, NULL, 0, 0);
- pixman_image_set_alpha_map (dst, NULL, 0, 0);
- pixman_image_set_alpha_map (orig_dst, NULL, 0, 0);
-
- pixman_image_unref (src);
- pixman_image_unref (dst);
- pixman_image_unref (orig_dst);
-
- return 0;
-}
-
-int
-main (int argc, char **argv)
-{
- int i, j, a, b, x, y;
-
- for (i = 0; i < ARRAY_LENGTH (formats); ++i)
- {
- for (j = 0; j < ARRAY_LENGTH (formats); ++j)
- {
- for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a)
- {
- for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b)
- {
- for (x = 0; x < ARRAY_LENGTH (origins); ++x)
- {
- for (y = 0; y < ARRAY_LENGTH (origins); ++y)
- {
- if (run_test (i, j, a, b, x, y) != 0)
- return 1;
- }
- }
- }
- }
- }
- }
-
- return 0;
-}
+#include <stdio.h> +#include <stdlib.h> +#include "utils.h" + +#define WIDTH 100 +#define HEIGHT 100 + +static const pixman_format_code_t formats[] = +{ + PIXMAN_a8r8g8b8, + PIXMAN_a2r10g10b10, + PIXMAN_a4r4g4b4, + PIXMAN_a8 +}; + +static const pixman_format_code_t alpha_formats[] = +{ + PIXMAN_null, + PIXMAN_a8, + PIXMAN_a2r10g10b10, + PIXMAN_a4r4g4b4 +}; + +static const int origins[] = +{ + 0, 10, -100 +}; + +static const char * +format_name (pixman_format_code_t format) +{ + if (format == PIXMAN_a8) + return "a8"; + else if (format == PIXMAN_a2r10g10b10) + return "a2r10g10b10"; + else if (format == PIXMAN_a8r8g8b8) + return "a8r8g8b8"; + else if (format == PIXMAN_a4r4g4b4) + return "a4r4g4b4"; + else if (format == PIXMAN_null) + return "none"; + else + assert (0); + + return "<unknown - bug in alphamap.c>"; +} + +static void +on_destroy (pixman_image_t *image, void *data) +{ + uint32_t *bits = pixman_image_get_data (image); + + fence_free (bits); +} + +static pixman_image_t * +make_image (pixman_format_code_t format) +{ + uint32_t *bits; + uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8; + pixman_image_t *image; + + bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); + + image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); + + if (image && bits) + pixman_image_set_destroy_function (image, on_destroy, NULL); + + return image; +} + +static pixman_image_t * +create_image (pixman_format_code_t format, pixman_format_code_t alpha_format, + int alpha_origin_x, int alpha_origin_y) +{ + pixman_image_t *image = make_image (format); + + if (alpha_format != PIXMAN_null) + { + pixman_image_t *alpha = make_image (alpha_format); + + pixman_image_set_alpha_map (image, alpha, + alpha_origin_x, alpha_origin_y); + pixman_image_unref (alpha); + } + + return image; +} + +static uint8_t +get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) +{ + uint8_t *bits; + uint8_t r; + + if (image->common.alpha_map) + { + if (x - orig_x >= 0 && x - orig_x < WIDTH && + y - orig_y >= 0 && y - orig_y < HEIGHT) + { + image = (pixman_image_t *)image->common.alpha_map; + + x -= orig_x; + y -= orig_y; + } + else + { + return 0; + } + } + + bits = (uint8_t *)image->bits.bits; + + if (image->bits.format == PIXMAN_a8) + { + r = bits[y * WIDTH + x]; + } + else if (image->bits.format == PIXMAN_a2r10g10b10) + { + r = ((uint32_t *)bits)[y * WIDTH + x] >> 30; + r |= r << 2; + r |= r << 4; + } + else if (image->bits.format == PIXMAN_a8r8g8b8) + { + r = ((uint32_t *)bits)[y * WIDTH + x] >> 24; + } + else if (image->bits.format == PIXMAN_a4r4g4b4) + { + r = ((uint16_t *)bits)[y * WIDTH + x] >> 12; + r |= r << 4; + } + else + { + assert (0); + } + + return r; +} + +#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) + +static int +run_test (int s, int d, int sa, int da, int soff, int doff) +{ + pixman_format_code_t sf = formats[s]; + pixman_format_code_t df = formats[d]; + pixman_format_code_t saf = alpha_formats[sa]; + pixman_format_code_t daf = alpha_formats[da]; + pixman_image_t *src, *dst, *orig_dst; + pixman_transform_t t1; + int j, k; + int n_alpha_bits; + + soff = origins[soff]; + doff = origins[doff]; + + n_alpha_bits = PIXMAN_FORMAT_A (df); + if (daf != PIXMAN_null) + n_alpha_bits = PIXMAN_FORMAT_A (daf); + + + src = create_image (sf, saf, soff, soff); + orig_dst = create_image (df, daf, doff, doff); + dst = create_image (df, daf, doff, doff); + + /* Transformations, repeats and filters on destinations should be ignored, + * so just set some random ones. + */ + pixman_transform_init_identity (&t1); + pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11)); + pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11)); + pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17)); + + pixman_image_set_transform (dst, &t1); + pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0); + pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT); + + pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst, + 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); + + pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst, + 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); + + for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j) + { + for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k) + { + uint8_t sa, da, oda, ref; + + sa = get_alpha (src, k, j, soff, soff); + da = get_alpha (dst, k, j, doff, doff); + oda = get_alpha (orig_dst, k, j, doff, doff); + + if (sa + oda > 255) + ref = 255; + else + ref = sa + oda; + + if (da >> (8 - n_alpha_bits) != ref >> (8 - n_alpha_bits)) + { + printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", + k, j, ref, da, sa, oda); + + printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", + format_name (sf), + format_name (saf), + soff, soff, + format_name (df), + format_name (daf), + doff, doff); + return 1; + } + } + } + + pixman_image_set_alpha_map (src, NULL, 0, 0); + pixman_image_set_alpha_map (dst, NULL, 0, 0); + pixman_image_set_alpha_map (orig_dst, NULL, 0, 0); + + pixman_image_unref (src); + pixman_image_unref (dst); + pixman_image_unref (orig_dst); + + return 0; +} + +int +main (int argc, char **argv) +{ + int i, j, a, b, x, y; + + for (i = 0; i < ARRAY_LENGTH (formats); ++i) + { + for (j = 0; j < ARRAY_LENGTH (formats); ++j) + { + for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a) + { + for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b) + { + for (x = 0; x < ARRAY_LENGTH (origins); ++x) + { + for (y = 0; y < ARRAY_LENGTH (origins); ++y) + { + if (run_test (i, j, a, b, x, y) != 0) + return 1; + } + } + } + } + } + } + + return 0; +} diff --git a/pixman/test/radial-test.c b/pixman/test/radial-test.c new file mode 100644 index 000000000..5d716c339 --- /dev/null +++ b/pixman/test/radial-test.c @@ -0,0 +1,198 @@ +#include "utils.h" +#include "gtk-utils.h" + +#define NUM_GRADIENTS 7 +#define NUM_STOPS 3 +#define NUM_REPEAT 4 +#define SIZE 128 +#define WIDTH (SIZE * NUM_GRADIENTS) +#define HEIGHT (SIZE * NUM_REPEAT) + +/* + * We want to test all the possible relative positions of the start + * and end circle: + * + * - The start circle can be smaller/equal/bigger than the end + * circle. A radial gradient can be classified in one of these + * three cases depending on the sign of dr. + * + * - The smaller circle can be completely inside/internally + * tangent/outside (at least in part) of the bigger circle. This + * classification is the same as the one which can be computed by + * examining the sign of a = (dx^2 + dy^2 - dr^2). + * + * - If the two circles have the same size, neither can be inside or + * internally tangent + * + * This test draws radial gradients whose circles always have the same + * centers (0, 0) and (1, 0), but with different radiuses. From left + * to right: + * + * - Small start circle completely inside the end circle + * 0.25 -> 1.75; dr = 1.5 > 0; a = 1 - 1.50^2 < 0 + * + * - Small start circle internally tangent to the end circle + * 0.50 -> 1.50; dr = 1.0 > 0; a = 1 - 1.00^2 = 0 + * + * - Small start circle outside of the end circle + * 0.50 -> 1.00; dr = 0.5 > 0; a = 1 - 0.50^2 > 0 + * + * - Start circle with the same size as the end circle + * 1.00 -> 1.00; dr = 0.0 = 0; a = 1 - 0.00^2 > 0 + * + * - Small end circle outside of the start circle + * 1.00 -> 0.50; dr = -0.5 > 0; a = 1 - 0.50^2 > 0 + * + * - Small end circle internally tangent to the start circle + * 1.50 -> 0.50; dr = -1.0 > 0; a = 1 - 1.00^2 = 0 + * + * - Small end circle completely inside the start circle + * 1.75 -> 0.25; dr = -1.5 > 0; a = 1 - 1.50^2 < 0 + * + */ + +const static double radiuses[NUM_GRADIENTS] = { + 0.25, + 0.50, + 0.50, + 1.00, + 1.00, + 1.50, + 1.75 +}; + +#define double_to_color(x) \ + (((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16)) + +#define PIXMAN_STOP(offset,r,g,b,a) \ + { pixman_double_to_fixed (offset), \ + { \ + double_to_color (r), \ + double_to_color (g), \ + double_to_color (b), \ + double_to_color (a) \ + } \ + } + +static const pixman_gradient_stop_t stops[NUM_STOPS] = { + PIXMAN_STOP (0.0, 1, 0, 0, 0.75), + PIXMAN_STOP (0.70710678, 0, 1, 0, 0), + PIXMAN_STOP (1.0, 0, 0, 1, 1) +}; + +static pixman_image_t * +create_radial (int index) +{ + pixman_point_fixed_t p0, p1; + pixman_fixed_t r0, r1; + double x0, x1, radius0, radius1, left, right, center; + + x0 = 0; + x1 = 1; + radius0 = radiuses[index]; + radius1 = radiuses[NUM_GRADIENTS - index - 1]; + + /* center the gradient */ + left = MIN (x0 - radius0, x1 - radius1); + right = MAX (x0 + radius0, x1 + radius1); + center = (left + right) * 0.5; + x0 -= center; + x1 -= center; + + /* scale to make it fit within a 1x1 rect centered in (0,0) */ + x0 *= 0.25; + x1 *= 0.25; + radius0 *= 0.25; + radius1 *= 0.25; + + p0.x = pixman_double_to_fixed (x0); + p0.y = pixman_double_to_fixed (0); + + p1.x = pixman_double_to_fixed (x1); + p1.y = pixman_double_to_fixed (0); + + r0 = pixman_double_to_fixed (radius0); + r1 = pixman_double_to_fixed (radius1); + + return pixman_image_create_radial_gradient (&p0, &p1, + r0, r1, + stops, NUM_STOPS); +} + +static const pixman_repeat_t repeat[NUM_REPEAT] = { + PIXMAN_REPEAT_NONE, + PIXMAN_REPEAT_NORMAL, + PIXMAN_REPEAT_REFLECT, + PIXMAN_REPEAT_PAD +}; + +int +main (int argc, char **argv) +{ + pixman_transform_t transform; + pixman_image_t *src_img, *dest_img; + int i, j; + + enable_fp_exceptions (); + + dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, + WIDTH, HEIGHT, + NULL, 0); + + pixman_transform_init_identity (&transform); + + /* + * The create_radial() function returns gradients centered in the + * origin and whose interesting part fits a 1x1 square. We want to + * paint these gradients on a SIZExSIZE square and to make things + * easier we want the origin in the top-left corner of the square + * we want to see. + */ + pixman_transform_translate (NULL, &transform, + pixman_double_to_fixed (0.5), + pixman_double_to_fixed (0.5)); + + pixman_transform_scale (NULL, &transform, + pixman_double_to_fixed (SIZE), + pixman_double_to_fixed (SIZE)); + + /* + * Gradients are evaluated at the center of each pixel, so we need + * to translate by half a pixel to trigger some interesting + * cornercases. In particular, the original implementation of PDF + * radial gradients tried to divide by 0 when using this transform + * on the "tangent circles" cases. + */ + pixman_transform_translate (NULL, &transform, + pixman_double_to_fixed (0.5), + pixman_double_to_fixed (0.5)); + + for (i = 0; i < NUM_GRADIENTS; i++) + { + src_img = create_radial (i); + pixman_image_set_transform (src_img, &transform); + + for (j = 0; j < NUM_REPEAT; j++) + { + pixman_image_set_repeat (src_img, repeat[j]); + + pixman_image_composite32 (PIXMAN_OP_OVER, + src_img, + NULL, + dest_img, + 0, 0, + 0, 0, + i * SIZE, j * SIZE, + SIZE, SIZE); + + } + + pixman_image_unref (src_img); + } + + show_image (dest_img); + + pixman_image_unref (dest_img); + + return 0; +} diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 1ceffe7cb..45286eaf4 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -2213,7 +2213,9 @@ hw/xfree86/doc/sgml/Makefile hw/xfree86/dri/Makefile hw/xfree86/dri2/Makefile hw/xfree86/exa/Makefile +hw/xfree86/exa/man/Makefile hw/xfree86/fbdevhw/Makefile +hw/xfree86/fbdevhw/man/Makefile hw/xfree86/i2c/Makefile hw/xfree86/int10/Makefile hw/xfree86/loader/Makefile @@ -2233,27 +2235,34 @@ hw/xfree86/vgahw/Makefile hw/xfree86/x86emu/Makefile hw/xfree86/xaa/Makefile hw/xfree86/utils/Makefile +hw/xfree86/utils/man/Makefile hw/xfree86/utils/cvt/Makefile hw/xfree86/utils/gtf/Makefile hw/dmx/config/Makefile +hw/dmx/config/man/Makefile hw/dmx/doc/Makefile hw/dmx/examples/Makefile hw/dmx/input/Makefile hw/dmx/glxProxy/Makefile hw/dmx/Makefile +hw/dmx/man/Makefile hw/vfb/Makefile +hw/vfb/man/Makefile hw/xnest/Makefile +hw/xnest/man/Makefile hw/xwin/Makefile hw/xwin/glx/Makefile +hw/xwin/man/Makefile hw/xquartz/Makefile hw/xquartz/GL/Makefile hw/xquartz/bundle/Makefile -hw/xquartz/doc/Makefile +hw/xquartz/man/Makefile hw/xquartz/mach-startup/Makefile hw/xquartz/pbproxy/Makefile hw/xquartz/xpr/Makefile hw/kdrive/Makefile hw/kdrive/ephyr/Makefile +hw/kdrive/ephyr/man/Makefile hw/kdrive/fake/Makefile hw/kdrive/fbdev/Makefile hw/kdrive/linux/Makefile diff --git a/xorg-server/cpprules.in b/xorg-server/cpprules.in deleted file mode 100644 index 6e435785a..000000000 --- a/xorg-server/cpprules.in +++ /dev/null @@ -1,49 +0,0 @@ -# -*- Makefile -*- -# Rules for generating files using the C pre-processor -# (Replaces CppFileTarget from Imake) - -SUFFIXES = .pre .man .man.pre - -# Translate XCOMM into pound sign with sed, rather than passing -DXCOMM=XCOMM -# to cpp, because that trick does not work on all ANSI C preprocessors. -# Delete line numbers from the cpp output (-P is not portable, I guess). -# Allow XCOMM to be preceded by whitespace and provide a means of generating -# output lines with trailing backslashes. -# Allow XHASH to always be substituted, even in cases where XCOMM isn't. - -CPP_SED_MAGIC = $(SED) -e '/^\# *[0-9][0-9]* *.*$$/d' \ - -e '/^\#line *[0-9][0-9]* *.*$$/d' \ - -e '/^[ ]*XCOMM$$/s/XCOMM/\#/' \ - -e '/^[ ]*XCOMM[^a-zA-Z0-9_]/s/XCOMM/\#/' \ - -e '/^[ ]*XHASH/s/XHASH/\#/' \ - -e '/\@\@$$/s/\@\@$$/\\/' - -# Strings to replace in man pages -XORGRELSTRING = @PACKAGE_STRING@ - XORGMANNAME = X Version 11 - XSERVERNAME = Xorg - -MANDEFS = \ - -D__vendorversion__="\"$(XORGRELSTRING)\" \"$(XORGMANNAME)\"" \ - -D__xorgversion__="\"$(XORGRELSTRING)\" \"$(XORGMANNAME)\"" \ - -D__appmansuffix__=$(APP_MAN_SUFFIX) \ - -D__filemansuffix__=$(FILE_MAN_SUFFIX) \ - -D__libmansuffix__=$(LIB_MAN_SUFFIX) \ - -D__miscmansuffix__=$(MISC_MAN_SUFFIX) \ - -D__drivermansuffix__=$(DRIVER_MAN_SUFFIX) \ - -D__adminmansuffix__=$(ADMIN_MAN_SUFFIX) \ - -D__mandir__=$(mandir) \ - -D__projectroot__=$(prefix) \ - -D__sysconfdir__=$(sysconfdir) \ - -D__datadir__=$(datadir) \ - -D__xconfigfile__=$(__XCONFIGFILE__) \ - -D__xconfigdir__=$(__XCONFIGDIR__) \ - -D__xkbdir__=$(XKB_BASE_DIRECTORY) \ - -D__modulepath__="$(DEFAULT_MODULE_PATH)" \ - -D__xlogfile__=$(XLOGFILE) -D__xservername__=$(XSERVERNAME) - -.pre: - $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) $(CPP_FILES_FLAGS) < $< | $(CPP_SED_MAGIC) > $@ - -.man.pre.man: - $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) $(MANDEFS) $(EXTRAMANDEFS) < $< | $(CPP_SED_MAGIC) > $@ diff --git a/xorg-server/doc/man/Makefile.am b/xorg-server/doc/man/Makefile.am index 5259a104f..71d704917 100644 --- a/xorg-server/doc/man/Makefile.am +++ b/xorg-server/doc/man/Makefile.am @@ -1,20 +1,6 @@ -# Xserver.man covers options generic to all X servers built in this tree
-# (i.e. those handled in the os/utils.c options processing instead of in
-# the DDX-level options processing)
-
-appmandir = $(APP_MAN_DIR)
-appman_PRE = Xserver.man
-appman_DATA = $(appman_PRE:man=$(APP_MAN_SUFFIX))
-
-EXTRA_DIST = $(appman_PRE)
-CLEANFILES = $(appman_DATA)
-SUFFIXES = .$(APP_MAN_SUFFIX) .man
-
-# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
-# 's|/,|/, |g' will add a space to help font path formatting
-MAN_SUBSTS += -e 's|__datadir__|$(datadir)|g' \
- -e 's|__default_font_path__|$(COMPILEDDEFAULTFONTPATH)|g' \
- -e '\|$(COMPILEDDEFAULTFONTPATH)| s|/,|/, |g'
-
-.man.$(APP_MAN_SUFFIX):
- $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
+# Xserver.man covers options generic to all X servers built in this tree +# (i.e. those handled in the os/utils.c options processing instead of in +# the DDX-level options processing) + +include $(top_srcdir)/manpages.am +appman_PRE = Xserver.man diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index e19c51e7a..3ef567d10 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/glx/glxcmds.c @@ -1,2213 +1,2362 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-#include <assert.h>
-
-#include "glxserver.h"
-#include <GL/glxtokens.h>
-#include <unpack.h>
-#include <pixmapstr.h>
-#include <windowstr.h>
-#include "glxutil.h"
-#include "glxext.h"
-#include "glapitable.h"
-#include "glapi.h"
-#include "glthread.h"
-#include "dispatch.h"
-#include "indirect_dispatch.h"
-#include "indirect_table.h"
-#include "indirect_util.h"
-
-static int
-validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err)
-{
- /*
- ** Check if screen exists.
- */
- if (screen >= screenInfo.numScreens) {
- client->errorValue = screen;
- *err = BadValue;
- return FALSE;
- }
- *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
-
- return TRUE;
-}
-
-static int
-validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
- __GLXconfig **config, int *err)
-{
- __GLXconfig *m;
-
- for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
- if (m->fbconfigID == id) {
- *config = m;
- return TRUE;
- }
-
- client->errorValue = id;
- *err = __glXError(GLXBadFBConfig);
-
- return FALSE;
-}
-
-static int
-validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
- __GLXconfig **config, int *err)
-{
- int i;
-
- for (i = 0; i < pGlxScreen->numVisuals; i++)
- if (pGlxScreen->visuals[i]->visualID == id) {
- *config = pGlxScreen->visuals[i];
- return TRUE;
- }
-
- client->errorValue = id;
- *err = BadValue;
-
- return FALSE;
-}
-
-static int
-validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config,
- DrawablePtr pDraw, int *err)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- VisualPtr pVisual = NULL;
- XID vid;
- int i;
-
- vid = wVisual((WindowPtr)pDraw);
- for (i = 0; i < pScreen->numVisuals; i++) {
- if (pScreen->visuals[i].vid == vid) {
- pVisual = &pScreen->visuals[i];
- break;
- }
- }
-
- /* FIXME: What exactly should we check here... */
- if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
- !(config->drawableType & GLX_WINDOW_BIT)) {
- client->errorValue = pDraw->id;
- *err = BadMatch;
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int
-validGlxContext(ClientPtr client, XID id, int access_mode,
- __GLXcontext **context, int *err)
-{
- *err = dixLookupResourceByType((pointer *) context, id,
- __glXContextRes, client, access_mode);
- if (*err != Success) {
- client->errorValue = id;
- if (*err == BadValue)
- *err = __glXError(GLXBadContext);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int
-validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
- __GLXdrawable **drawable, int *err)
-{
- int rc;
-
- rc = dixLookupResourceByType((pointer *) drawable, id,
- __glXDrawableRes, client, access_mode);
- if (rc != Success && rc != BadValue) {
- *err = rc;
- client->errorValue = id;
- return FALSE;
- }
-
- /* If the ID of the glx drawable we looked up doesn't match the id
- * we looked for, it's because we looked it up under the X
- * drawable ID (see DoCreateGLXDrawable). */
- if (rc == BadValue ||
- (*drawable)->drawId != id ||
- (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
- client->errorValue = id;
- switch (type) {
- case GLX_DRAWABLE_WINDOW:
- *err = __glXError(GLXBadWindow);
- return FALSE;
- case GLX_DRAWABLE_PIXMAP:
- *err = __glXError(GLXBadPixmap);
- return FALSE;
- case GLX_DRAWABLE_PBUFFER:
- *err = __glXError(GLXBadPbuffer);
- return FALSE;
- case GLX_DRAWABLE_ANY:
- *err = __glXError(GLXBadDrawable);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-void
-__glXContextDestroy(__GLXcontext *context)
-{
- __glXFlushContextCache();
-}
-
-static void __glXdirectContextDestroy(__GLXcontext *context)
-{
- __glXContextDestroy(context);
- free(context);
-}
-
-static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
- __GLXconfig *modes,
- __GLXcontext *shareContext)
-{
- __GLXcontext *context;
-
- context = calloc(1, sizeof (__GLXcontext));
- if (context == NULL)
- return NULL;
-
- context->destroy = __glXdirectContextDestroy;
-
- return context;
-}
-
-/**
- * Create a GL context with the given properties. This routine is used
- * to implement \c glXCreateContext, \c glXCreateNewContext, and
- * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way
- * that GLXFBConfigs are implemented. Basically, the FBConfigID is the
- * same as the VisualID.
- */
-
-static int
-DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
- GLXContextID shareList, __GLXconfig *config,
- __GLXscreen *pGlxScreen, GLboolean isDirect)
-{
- ClientPtr client = cl->client;
- __GLXcontext *glxc, *shareglxc;
- int err;
-
- LEGAL_NEW_RESOURCE(gcId, client);
-
- /*
- ** Find the display list space that we want to share.
- **
- ** NOTE: In a multithreaded X server, we would need to keep a reference
- ** count for each display list so that if one client detroyed a list that
- ** another client was using, the list would not really be freed until it
- ** was no longer in use. Since this sample implementation has no support
- ** for multithreaded servers, we don't do this.
- */
- if (shareList == None) {
- shareglxc = 0;
- } else {
- if (!validGlxContext(client, shareList, DixReadAccess,
- &shareglxc, &err))
- return err;
-
- if (shareglxc->isDirect) {
- /*
- ** NOTE: no support for sharing display lists between direct
- ** contexts, even if they are in the same address space.
- */
-#if 0
- /* Disabling this code seems to allow shared display lists
- * and texture objects to work. We'll leave it disabled for now.
- */
- client->errorValue = shareList;
- return BadMatch;
-#endif
- } else {
- /*
- ** Create an indirect context regardless of what the client asked
- ** for; this way we can share display list space with shareList.
- */
- isDirect = GL_FALSE;
- }
- }
-
- /*
- ** Allocate memory for the new context
- */
- if (!isDirect)
- glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc);
- else
- glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
- if (!glxc) {
- return BadAlloc;
- }
-
- /*
- ** Initially, setup the part of the context that could be used by
- ** a GL core that needs windowing information (e.g., Mesa).
- */
- glxc->pGlxScreen = pGlxScreen;
- glxc->config = config;
-
- /*
- ** Register this context as a resource.
- */
- if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
- (*glxc->destroy)(glxc);
- client->errorValue = gcId;
- return BadAlloc;
- }
-
- /*
- ** Finally, now that everything is working, setup the rest of the
- ** context.
- */
- glxc->id = gcId;
- glxc->share_id = shareList;
- glxc->idExists = GL_TRUE;
- glxc->isCurrent = GL_FALSE;
- glxc->isDirect = isDirect;
- glxc->renderMode = GL_RENDER;
-
- __glXAddToContextList(glxc);
-
- return Success;
-}
-
-int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- int err;
-
- if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
- return err;
- if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
- return err;
-
- return DoCreateContext(cl, req->context, req->shareList,
- config, pGlxScreen, req->isDirect);
-}
-
-int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- int err;
-
- if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
- return err;
- if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
- return err;
-
- return DoCreateContext(cl, req->context, req->shareList,
- config, pGlxScreen, req->isDirect);
-}
-
-int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextWithConfigSGIXReq *req =
- (xGLXCreateContextWithConfigSGIXReq *) pc;
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- int err;
-
- if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
- return err;
- if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
- return err;
-
- return DoCreateContext(cl, req->context, req->shareList,
- config, pGlxScreen, req->isDirect);
-}
-int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
- __GLXcontext *glxc;
- int err;
-
- if (!validGlxContext(cl->client, req->context, DixDestroyAccess,
- &glxc, &err))
- return err;
-
- FreeResourceByType(req->context, __glXContextRes, FALSE);
- return Success;
-}
-
-/*****************************************************************************/
-
-/*
-** For each client, the server keeps a table of all the contexts that are
-** current for that client (each thread of a client may have its own current
-** context). These routines add, change, and lookup contexts in the table.
-*/
-
-/*
-** Add a current context, and return the tag that will be used to refer to it.
-*/
-static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc)
-{
- int i;
- int num = cl->numCurrentContexts;
- __GLXcontext **table = cl->currentContexts;
-
- if (!glxc) return -1;
-
- /*
- ** Try to find an empty slot and use it.
- */
- for (i=0; i < num; i++) {
- if (!table[i]) {
- table[i] = glxc;
- return i+1;
- }
- }
- /*
- ** Didn't find a free slot, so we'll have to grow the table.
- */
- if (!num) {
- table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
- } else {
- table = (__GLXcontext **) realloc(table,
- (num+1)*sizeof(__GLXcontext *));
- }
- table[num] = glxc;
- cl->currentContexts = table;
- cl->numCurrentContexts++;
- return num+1;
-}
-
-/*
-** Given a tag, change the current context for the corresponding entry.
-*/
-static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
- GLXContextTag tag)
-{
- __GLXcontext **table = cl->currentContexts;
- table[tag-1] = glxc;
-}
-
-/*
-** For this implementation we have chosen to simply use the index of the
-** context's entry in the table as the context tag. A tag must be greater
-** than 0.
-*/
-__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
-{
- int num = cl->numCurrentContexts;
-
- if (tag < 1 || tag > num) {
- return 0;
- } else {
- return cl->currentContexts[tag-1];
- }
-}
-
-/*****************************************************************************/
-
-static void StopUsingContext(__GLXcontext *glxc)
-{
- if (glxc) {
- if (glxc == __glXLastContext) {
- /* Tell server GL library */
- __glXLastContext = 0;
- }
- glxc->isCurrent = GL_FALSE;
- if (!glxc->idExists) {
- __glXFreeContext(glxc);
- }
- }
-}
-
-static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
-{
- glxc->isCurrent = GL_TRUE;
- __glXLastContext = glxc;
-}
-
-/**
- * This is a helper function to handle the legacy (pre GLX 1.3) cases
- * where passing an X window to glXMakeCurrent is valid. Given a
- * resource ID, look up the GLX drawable if available, otherwise, make
- * sure it's an X window and create a GLX drawable one the fly.
- */
-static __GLXdrawable *
-__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
- int *error)
-{
- DrawablePtr pDraw;
- __GLXdrawable *pGlxDraw;
- int rc;
-
- if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
- DixWriteAccess, &pGlxDraw, &rc)) {
- if (glxc != NULL && pGlxDraw->config != glxc->config) {
- client->errorValue = drawId;
- *error = BadMatch;
- return NULL;
- }
-
- return pGlxDraw;
- }
-
- /* No active context and an unknown drawable, bail. */
- if (glxc == NULL) {
- client->errorValue = drawId;
- *error = BadMatch;
- return NULL;
- }
-
- /* The drawId wasn't a GLX drawable. Make sure it's a window and
- * create a GLXWindow for it. Check that the drawable screen
- * matches the context screen and that the context fbconfig is
- * compatible with the window visual. */
-
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
- if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
- client->errorValue = drawId;
- *error = __glXError(GLXBadDrawable);
- return NULL;
- }
-
- if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
- client->errorValue = pDraw->pScreen->myNum;
- *error = BadMatch;
- return NULL;
- }
-
- if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
- return NULL;
-
- pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
- pDraw, drawId,
- GLX_DRAWABLE_WINDOW,
- drawId, glxc->config);
-
- /* since we are creating the drawablePrivate, drawId should be new */
- if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
- pGlxDraw->destroy (pGlxDraw);
- *error = BadAlloc;
- return NULL;
- }
-
- return pGlxDraw;
-}
-
-/*****************************************************************************/
-/*
-** Make an OpenGL context and drawable current.
-*/
-
-static int
-DoMakeCurrent(__GLXclientState *cl,
- GLXDrawable drawId, GLXDrawable readId,
- GLXContextID contextId, GLXContextTag tag)
-{
- ClientPtr client = cl->client;
- xGLXMakeCurrentReply reply;
- __GLXcontext *glxc, *prevglxc;
- __GLXdrawable *drawPriv = NULL;
- __GLXdrawable *readPriv = NULL;
- int error;
- GLuint mask;
-
- /*
- ** If one is None and the other isn't, it's a bad match.
- */
-
- mask = (drawId == None) ? (1 << 0) : 0;
- mask |= (readId == None) ? (1 << 1) : 0;
- mask |= (contextId == None) ? (1 << 2) : 0;
-
- if ( (mask != 0x00) && (mask != 0x07) ) {
- return BadMatch;
- }
-
- /*
- ** Lookup old context. If we have one, it must be in a usable state.
- */
- if (tag != 0) {
- prevglxc = __glXLookupContextByTag(cl, tag);
- if (!prevglxc) {
- /*
- ** Tag for previous context is invalid.
- */
- return __glXError(GLXBadContextTag);
- }
- if (prevglxc->renderMode != GL_RENDER) {
- /* Oops. Not in render mode render. */
- client->errorValue = prevglxc->id;
- return __glXError(GLXBadContextState);
- }
- } else {
- prevglxc = 0;
- }
-
- /*
- ** Lookup new context. It must not be current for someone else.
- */
- if (contextId != None) {
- int status;
-
- if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error))
- return error;
- if ((glxc != prevglxc) && glxc->isCurrent) {
- /* Context is current to somebody else */
- return BadAccess;
- }
-
- assert( drawId != None );
- assert( readId != None );
-
- drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
- if (drawPriv == NULL)
- return status;
-
- readPriv = __glXGetDrawable(glxc, readId, client, &status);
- if (readPriv == NULL)
- return status;
-
- } else {
- /* Switching to no context. Ignore new drawable. */
- glxc = 0;
- drawPriv = 0;
- readPriv = 0;
- }
-
-
- if (prevglxc) {
- /*
- ** Flush the previous context if needed.
- */
- if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) {
- if (__glXForceCurrent(cl, tag, (int *)&error)) {
- CALL_Flush( GET_DISPATCH(), () );
- __GLX_NOTE_FLUSHED_CMDS(prevglxc);
- } else {
- return error;
- }
- }
-
- /*
- ** Make the previous context not current.
- */
- if (!(*prevglxc->loseCurrent)(prevglxc)) {
- return __glXError(GLXBadContext);
- }
- __glXFlushContextCache();
- if (!prevglxc->isDirect) {
- prevglxc->drawPriv = NULL;
- prevglxc->readPriv = NULL;
- }
- }
-
-
- if ((glxc != 0) && !glxc->isDirect) {
-
- glxc->drawPriv = drawPriv;
- glxc->readPriv = readPriv;
-
- /* make the context current */
- if (!(*glxc->makeCurrent)(glxc)) {
- glxc->drawPriv = NULL;
- glxc->readPriv = NULL;
- return __glXError(GLXBadContext);
- }
-
- glxc->isCurrent = GL_TRUE;
- }
-
- if (prevglxc) {
- ChangeCurrentContext(cl, glxc, tag);
- StopUsingContext(prevglxc);
- } else {
- tag = AddCurrentContext(cl, glxc);
- }
-
- if (glxc) {
- StartUsingContext(cl, glxc);
- reply.contextTag = tag;
- } else {
- reply.contextTag = 0;
- }
-
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __glXSwapMakeCurrentReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)&reply);
- }
- return Success;
-}
-
-int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
-
- return DoMakeCurrent( cl, req->drawable, req->drawable,
- req->context, req->oldContextTag );
-}
-
-int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
-
- return DoMakeCurrent( cl, req->drawable, req->readdrawable,
- req->context, req->oldContextTag );
-}
-
-int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
-
- return DoMakeCurrent( cl, req->drawable, req->readable,
- req->context, req->oldContextTag );
-}
-
-int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
- xGLXIsDirectReply reply;
- __GLXcontext *glxc;
- int err;
-
- if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err))
- return err;
-
- reply.isDirect = glxc->isDirect;
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __glXSwapIsDirectReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
- }
-
- return Success;
-}
-
-int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
- xGLXQueryVersionReply reply;
- GLuint major, minor;
-
- major = req->majorVersion;
- minor = req->minorVersion;
- (void)major;
- (void)minor;
-
- /*
- ** Server should take into consideration the version numbers sent by the
- ** client if it wants to work with older clients; however, in this
- ** implementation the server just returns its version number.
- */
- reply.majorVersion = glxMajorVersion;
- reply.minorVersion = glxMinorVersion;
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __glXSwapQueryVersionReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
- }
- return Success;
-}
-
-int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
- GLXContextTag tag = req->contextTag;
- __GLXcontext *glxc = NULL;
- int error;
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc)
- return __glXError(GLXBadContextTag);
-
- if (!__glXForceCurrent(cl, req->contextTag, &error))
- return error;
-
- CALL_Finish( GET_DISPATCH(), () );
- }
-
- if (glxc && glxc->drawPriv->waitGL)
- (*glxc->drawPriv->waitGL)(glxc->drawPriv);
-
- return Success;
-}
-
-int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
- GLXContextTag tag = req->contextTag;
- __GLXcontext *glxc = NULL;
- int error;
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc)
- return __glXError(GLXBadContextTag);
-
- if (!__glXForceCurrent(cl, req->contextTag, &error))
- return error;
- }
-
- if (glxc && glxc->drawPriv->waitX)
- (*glxc->drawPriv->waitX)(glxc->drawPriv);
-
- return Success;
-}
-
-int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
- GLXContextID source = req->source;
- GLXContextID dest = req->dest;
- GLXContextTag tag = req->contextTag;
- unsigned long mask = req->mask;
- __GLXcontext *src, *dst;
- int error;
-
- if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error))
- return error;
- if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error))
- return error;
-
- /*
- ** They must be in the same address space, and same screen.
- ** NOTE: no support for direct rendering contexts here.
- */
- if (src->isDirect || dst->isDirect ||
- (src->pGlxScreen != dst->pGlxScreen)) {
- client->errorValue = source;
- return BadMatch;
- }
-
- /*
- ** The destination context must not be current for any client.
- */
- if (dst->isCurrent) {
- client->errorValue = dest;
- return BadAccess;
- }
-
- if (tag) {
- __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
-
- if (!tagcx) {
- return __glXError(GLXBadContextTag);
- }
- if (tagcx != src) {
- /*
- ** This would be caused by a faulty implementation of the client
- ** library.
- */
- return BadMatch;
- }
- /*
- ** In this case, glXCopyContext is in both GL and X streams, in terms
- ** of sequentiality.
- */
- if (__glXForceCurrent(cl, tag, &error)) {
- /*
- ** Do whatever is needed to make sure that all preceding requests
- ** in both streams are completed before the copy is executed.
- */
- CALL_Finish( GET_DISPATCH(), () );
- __GLX_NOTE_FLUSHED_CMDS(tagcx);
- } else {
- return error;
- }
- }
- /*
- ** Issue copy. The only reason for failure is a bad mask.
- */
- if (!(*dst->copy)(dst, src, mask)) {
- client->errorValue = mask;
- return BadValue;
- }
- return Success;
-}
-
-enum {
- GLX_VIS_CONFIG_UNPAIRED = 18,
- GLX_VIS_CONFIG_PAIRED = 20
-};
-
-enum {
- GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
-};
-
-int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
- ClientPtr client = cl->client;
- xGLXGetVisualConfigsReply reply;
- __GLXscreen *pGlxScreen;
- __GLXconfig *modes;
- CARD32 buf[GLX_VIS_CONFIG_TOTAL];
- int p, i, err;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
- return err;
-
- reply.numVisuals = pGlxScreen->numVisuals;
- reply.numProps = GLX_VIS_CONFIG_TOTAL;
- reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.numVisuals);
- __GLX_SWAP_INT(&reply.numProps);
- }
-
- WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
-
- for (i = 0; i < pGlxScreen->numVisuals; i++) {
- modes = pGlxScreen->visuals[i];
-
- p = 0;
- buf[p++] = modes->visualID;
- buf[p++] = glxConvertToXVisualType( modes->visualType );
- buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE;
-
- buf[p++] = modes->redBits;
- buf[p++] = modes->greenBits;
- buf[p++] = modes->blueBits;
- buf[p++] = modes->alphaBits;
- buf[p++] = modes->accumRedBits;
- buf[p++] = modes->accumGreenBits;
- buf[p++] = modes->accumBlueBits;
- buf[p++] = modes->accumAlphaBits;
-
- buf[p++] = modes->doubleBufferMode;
- buf[p++] = modes->stereoMode;
-
- buf[p++] = modes->rgbBits;
- buf[p++] = modes->depthBits;
- buf[p++] = modes->stencilBits;
- buf[p++] = modes->numAuxBuffers;
- buf[p++] = modes->level;
-
- assert(p == GLX_VIS_CONFIG_UNPAIRED);
- /*
- ** Add token/value pairs for extensions.
- */
- buf[p++] = GLX_VISUAL_CAVEAT_EXT;
- buf[p++] = modes->visualRating;
- buf[p++] = GLX_TRANSPARENT_TYPE;
- buf[p++] = modes->transparentPixel;
- buf[p++] = GLX_TRANSPARENT_RED_VALUE;
- buf[p++] = modes->transparentRed;
- buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
- buf[p++] = modes->transparentGreen;
- buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
- buf[p++] = modes->transparentBlue;
- buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
- buf[p++] = modes->transparentAlpha;
- buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
- buf[p++] = modes->transparentIndex;
- buf[p++] = GLX_SAMPLES_SGIS;
- buf[p++] = modes->samples;
- buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
- buf[p++] = modes->sampleBuffers;
- buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */
- buf[p++] = 0;
-
- assert(p == GLX_VIS_CONFIG_TOTAL);
- if (client->swapped) {
- __GLX_SWAP_INT_ARRAY(buf, p);
- }
- WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf);
- }
- return Success;
-}
-
-#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36)
-#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
-/**
- * Send the set of GLXFBConfigs to the client. There is not currently
- * and interface into the driver on the server-side to get GLXFBConfigs,
- * so we "invent" some based on the \c __GLXvisualConfig structures that
- * the driver does supply.
- *
- * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
- * is the same, so this routine pulls double duty.
- */
-
-static int
-DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
-{
- ClientPtr client = cl->client;
- xGLXGetFBConfigsReply reply;
- __GLXscreen *pGlxScreen;
- CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
- int p, err;
- __GLXconfig *modes;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
- return err;
-
- reply.numFBConfigs = pGlxScreen->numFBConfigs;
- reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS;
- reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs);
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.numFBConfigs);
- __GLX_SWAP_INT(&reply.numAttribs);
- }
-
- WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
-
- for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
- p = 0;
-
-#define WRITE_PAIR(tag,value) \
- do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
-
- WRITE_PAIR( GLX_VISUAL_ID, modes->visualID );
- WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID );
- WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE );
-
- WRITE_PAIR( GLX_RGBA,
- (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE );
- WRITE_PAIR( GLX_RENDER_TYPE, modes->renderType );
- WRITE_PAIR( GLX_DOUBLEBUFFER, modes->doubleBufferMode );
- WRITE_PAIR( GLX_STEREO, modes->stereoMode );
-
- WRITE_PAIR( GLX_BUFFER_SIZE, modes->rgbBits );
- WRITE_PAIR( GLX_LEVEL, modes->level );
- WRITE_PAIR( GLX_AUX_BUFFERS, modes->numAuxBuffers );
- WRITE_PAIR( GLX_RED_SIZE, modes->redBits );
- WRITE_PAIR( GLX_GREEN_SIZE, modes->greenBits );
- WRITE_PAIR( GLX_BLUE_SIZE, modes->blueBits );
- WRITE_PAIR( GLX_ALPHA_SIZE, modes->alphaBits );
- WRITE_PAIR( GLX_ACCUM_RED_SIZE, modes->accumRedBits );
- WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits );
- WRITE_PAIR( GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits );
- WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits );
- WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits );
- WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits );
- WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType );
- WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating );
- WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel );
- WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed );
- WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen );
- WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue );
- WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha );
- WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex );
- WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod );
- WRITE_PAIR( GLX_SAMPLES_SGIS, modes->samples );
- WRITE_PAIR( GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers );
- /* GLX_VISUAL_SELECT_GROUP_SGIX ? */
- WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType );
- WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb );
- WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba );
- WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture );
- WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets );
-
- if (client->swapped) {
- __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
- }
- WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
- (char *)buf);
- }
- return Success;
-}
-
-
-int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
- return DoGetFBConfigs(cl, req->screen);
-}
-
-int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
- return DoGetFBConfigs(cl, req->screen);
-}
-
-GLboolean
-__glXDrawableInit(__GLXdrawable *drawable,
- __GLXscreen *screen, DrawablePtr pDraw, int type,
- XID drawId, __GLXconfig *config)
-{
- drawable->pDraw = pDraw;
- drawable->type = type;
- drawable->drawId = drawId;
- drawable->config = config;
- drawable->eventMask = 0;
-
- return GL_TRUE;
-}
-
-void
-__glXDrawableRelease(__GLXdrawable *drawable)
-{
-}
-
-static int
-DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
- __GLXconfig *config, DrawablePtr pDraw, XID drawableId,
- XID glxDrawableId, int type)
-{
- __GLXdrawable *pGlxDraw;
-
- if (pGlxScreen->pScreen != pDraw->pScreen)
- return BadMatch;
-
- pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
- drawableId, type,
- glxDrawableId, config);
- if (pGlxDraw == NULL)
- return BadAlloc;
-
- if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
- pGlxDraw->destroy (pGlxDraw);
- return BadAlloc;
- }
-
- /* Add the glx drawable under the XID of the underlying X drawable
- * too. That way we'll get a callback in DrawableGone and can
- * clean up properly when the drawable is destroyed. */
- if (drawableId != glxDrawableId &&
- !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
- pGlxDraw->destroy (pGlxDraw);
- return BadAlloc;
- }
-
- return Success;
-}
-
-static int
-DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
- XID drawableId, XID glxDrawableId)
-{
- DrawablePtr pDraw;
- int err;
-
- LEGAL_NEW_RESOURCE(glxDrawableId, client);
-
- err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
- if (err != Success) {
- client->errorValue = drawableId;
- return err;
- }
- if (pDraw->type != DRAWABLE_PIXMAP) {
- client->errorValue = drawableId;
- return BadPixmap;
- }
-
- err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
- glxDrawableId, GLX_DRAWABLE_PIXMAP);
-
- return err;
-}
-
-static void
-determineTextureTarget(ClientPtr client, XID glxDrawableID,
- CARD32 *attribs, CARD32 numAttribs)
-{
- GLenum target = 0;
- GLenum format = 0;
- int i, err;
- __GLXdrawable *pGlxDraw;
-
- if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
- DixWriteAccess, &pGlxDraw, &err))
- /* We just added it in CreatePixmap, so we should never get here. */
- return;
-
- for (i = 0; i < numAttribs; i++) {
- if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
- switch (attribs[2 * i + 1]) {
- case GLX_TEXTURE_2D_EXT:
- target = GL_TEXTURE_2D;
- break;
- case GLX_TEXTURE_RECTANGLE_EXT:
- target = GL_TEXTURE_RECTANGLE_ARB;
- break;
- }
- }
-
- if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
- format = attribs[2 * i + 1];
- }
-
- if (!target) {
- int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
-
- if (h & (h - 1) || w & (w - 1))
- target = GL_TEXTURE_RECTANGLE_ARB;
- else
- target = GL_TEXTURE_2D;
- }
-
- pGlxDraw->target = target;
- pGlxDraw->format = format;
-}
-
-int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- int err;
-
- if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
- return err;
- if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
- return err;
-
- return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
- req->pixmap, req->glxpixmap);
-}
-
-int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- int err;
-
- if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
- return err;
- if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
- return err;
-
- err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
- req->pixmap, req->glxpixmap);
- if (err != Success)
- return err;
-
- determineTextureTarget(cl->client, req->glxpixmap,
- (CARD32*) (req + 1), req->numAttribs);
-
- return Success;
-}
-
-int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPixmapWithConfigSGIXReq *req =
- (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- int err;
-
- if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
- return err;
- if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
- return err;
-
- return DoCreateGLXPixmap(cl->client, pGlxScreen,
- config, req->pixmap, req->glxpixmap);
-}
-
-
-static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
-{
- __GLXdrawable *pGlxDraw;
- int err;
-
- if (!validGlxDrawable(cl->client, glxdrawable, type,
- DixDestroyAccess, &pGlxDraw, &err))
- return err;
-
- FreeResource(glxdrawable, FALSE);
-
- return Success;
-}
-
-int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
-
- return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
-}
-
-int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
-
- return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
-}
-
-static int
-DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
- int width, int height, XID glxDrawableId)
-{
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- PixmapPtr pPixmap;
- int err;
-
- LEGAL_NEW_RESOURCE(glxDrawableId, client);
-
- if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
- return err;
- if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
- return err;
-
- __glXenterServer(GL_FALSE);
- pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
- width, height, config->rgbBits, 0);
- __glXleaveServer(GL_FALSE);
-
- /* Assign the pixmap the same id as the pbuffer and add it as a
- * resource so it and the DRI2 drawable will be reclaimed when the
- * pbuffer is destroyed. */
- pPixmap->drawable.id = glxDrawableId;
- if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
- return BadAlloc;
-
- return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
- glxDrawableId, glxDrawableId,
- GLX_DRAWABLE_PBUFFER);
-}
-
-int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
- CARD32 *attrs;
- int width, height, i;
-
- attrs = (CARD32 *) (req + 1);
- width = 0;
- height = 0;
-
- for (i = 0; i < req->numAttribs; i++) {
- switch (attrs[i * 2]) {
- case GLX_PBUFFER_WIDTH:
- width = attrs[i * 2 + 1];
- break;
- case GLX_PBUFFER_HEIGHT:
- height = attrs[i * 2 + 1];
- break;
- case GLX_LARGEST_PBUFFER:
- case GLX_PRESERVED_CONTENTS:
- /* FIXME: huh... */
- break;
- }
- }
-
- return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
- width, height, req->pbuffer);
-}
-
-int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
-
- return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
- req->width, req->height, req->pbuffer);
-}
-
-int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
-
- return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
-}
-
-int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
-
- return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
-}
-
-static int
-DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
- int numAttribs, CARD32 *attribs)
-{
- __GLXdrawable *pGlxDraw;
- int i, err;
-
- if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
- DixSetAttrAccess, &pGlxDraw, &err))
- return err;
-
- for (i = 0; i < numAttribs; i++) {
- switch(attribs[i * 2]) {
- case GLX_EVENT_MASK:
- /* All we do is to record the event mask so we can send it
- * back when queried. We never actually clobber the
- * pbuffers, so we never need to send out the event. */
- pGlxDraw->eventMask = attribs[i * 2 + 1];
- break;
- }
- }
-
- return Success;
-}
-
-int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXChangeDrawableAttributesReq *req =
- (xGLXChangeDrawableAttributesReq *) pc;
-
- return DoChangeDrawableAttributes(cl->client, req->drawable,
- req->numAttribs, (CARD32 *) (req + 1));
-}
-
-int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXChangeDrawableAttributesSGIXReq *req =
- (xGLXChangeDrawableAttributesSGIXReq *)pc;
-
- return DoChangeDrawableAttributes(cl->client, req->drawable,
- req->numAttribs, (CARD32 *) (req + 1));
-}
-
-int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
- __GLXconfig *config;
- __GLXscreen *pGlxScreen;
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- int err;
-
- LEGAL_NEW_RESOURCE(req->glxwindow, client);
-
- if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
- return err;
- if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
- return err;
-
- err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess);
- if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
- client->errorValue = req->window;
- return BadWindow;
- }
-
- if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
- return err;
-
- return DoCreateGLXDrawable(client, pGlxScreen, config,
- pDraw, req->window,
- req->glxwindow, GLX_DRAWABLE_WINDOW);
-}
-
-int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
-
- return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
-}
-
-
-/*****************************************************************************/
-
-/*
-** NOTE: There is no portable implementation for swap buffers as of
-** this time that is of value. Consequently, this code must be
-** implemented by somebody other than SGI.
-*/
-int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
- GLXContextTag tag = req->contextTag;
- XID drawId = req->drawable;
- __GLXcontext *glxc = NULL;
- __GLXdrawable *pGlxDraw;
- int error;
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc) {
- return __glXError(GLXBadContextTag);
- }
- /*
- ** The calling thread is swapping its current drawable. In this case,
- ** glxSwapBuffers is in both GL and X streams, in terms of
- ** sequentiality.
- */
- if (__glXForceCurrent(cl, tag, &error)) {
- /*
- ** Do whatever is needed to make sure that all preceding requests
- ** in both streams are completed before the swap is executed.
- */
- CALL_Finish( GET_DISPATCH(), () );
- __GLX_NOTE_FLUSHED_CMDS(glxc);
- } else {
- return error;
- }
- }
-
- pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
- if (pGlxDraw == NULL)
- return error;
-
- if (pGlxDraw->type == DRAWABLE_WINDOW &&
- (*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE)
- return __glXError(GLXBadDrawable);
-
- return Success;
-}
-
-
-static int
-DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
-{
- ClientPtr client = cl->client;
- __GLXcontext *ctx;
- xGLXQueryContextInfoEXTReply reply;
- int nProps;
- int *sendBuf, *pSendBuf;
- int nReplyBytes;
- int err;
-
- if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err))
- return err;
-
- nProps = 3;
- reply.length = nProps << 1;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.n = nProps;
-
- nReplyBytes = reply.length << 2;
- sendBuf = (int *)malloc((size_t)nReplyBytes);
- if (sendBuf == NULL) {
- return __glXError(GLXBadContext); /* XXX: Is this correct? */
- }
- pSendBuf = sendBuf;
- *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
- *pSendBuf++ = (int)(ctx->share_id);
- *pSendBuf++ = GLX_VISUAL_ID_EXT;
- *pSendBuf++ = (int)(ctx->config->visualID);
- *pSendBuf++ = GLX_SCREEN_EXT;
- *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum);
-
- if (client->swapped) {
- __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
- } else {
- WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
- WriteToClient(client, nReplyBytes, (char *)sendBuf);
- }
- free((char *)sendBuf);
-
- return Success;
-}
-
-int __glXDisp_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
-
- return DoQueryContext(cl, req->context);
-}
-
-int __glXDisp_QueryContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
-
- return DoQueryContext(cl, req->context);
-}
-
-int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- ClientPtr client = cl->client;
- __GLXcontext *context;
- __GLXdrawable *pGlxDraw;
- GLXDrawable drawId;
- int buffer;
- int error;
-
- pc += __GLX_VENDPRIV_HDR_SIZE;
-
- drawId = *((CARD32 *) (pc));
- buffer = *((INT32 *) (pc + 4));
-
- if (buffer != GLX_FRONT_LEFT_EXT)
- return __glXError(GLXBadPixmap);
-
- context = __glXForceCurrent (cl, req->contextTag, &error);
- if (!context)
- return error;
-
- if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
- DixReadAccess, &pGlxDraw, &error))
- return error;
-
- if (!context->textureFromPixmap)
- return __glXError(GLXUnsupportedPrivateRequest);
-
- return context->textureFromPixmap->bindTexImage(context,
- buffer,
- pGlxDraw);
-}
-
-int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- ClientPtr client = cl->client;
- __GLXdrawable *pGlxDraw;
- __GLXcontext *context;
- GLXDrawable drawId;
- int buffer;
- int error;
-
- pc += __GLX_VENDPRIV_HDR_SIZE;
-
- drawId = *((CARD32 *) (pc));
- buffer = *((INT32 *) (pc + 4));
-
- context = __glXForceCurrent (cl, req->contextTag, &error);
- if (!context)
- return error;
-
- if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
- DixReadAccess, &pGlxDraw, &error))
- return error;
-
- if (!context->textureFromPixmap)
- return __glXError(GLXUnsupportedPrivateRequest);
-
- return context->textureFromPixmap->releaseTexImage(context,
- buffer,
- pGlxDraw);
-}
-
-int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- GLXContextTag tag = req->contextTag;
- __GLXcontext *glxc = NULL;
- __GLXdrawable *pGlxDraw;
- ClientPtr client = cl->client;
- GLXDrawable drawId;
- int error;
- int x, y, width, height;
-
- (void) client;
- (void) req;
-
- pc += __GLX_VENDPRIV_HDR_SIZE;
-
- drawId = *((CARD32 *) (pc));
- x = *((INT32 *) (pc + 4));
- y = *((INT32 *) (pc + 8));
- width = *((INT32 *) (pc + 12));
- height = *((INT32 *) (pc + 16));
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc) {
- return __glXError(GLXBadContextTag);
- }
- /*
- ** The calling thread is swapping its current drawable. In this case,
- ** glxSwapBuffers is in both GL and X streams, in terms of
- ** sequentiality.
- */
- if (__glXForceCurrent(cl, tag, &error)) {
- /*
- ** Do whatever is needed to make sure that all preceding requests
- ** in both streams are completed before the swap is executed.
- */
- CALL_Finish( GET_DISPATCH(), () );
- __GLX_NOTE_FLUSHED_CMDS(glxc);
- } else {
- return error;
- }
- }
-
- pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
- if (!pGlxDraw)
- return error;
-
- if (pGlxDraw == NULL ||
- pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
- pGlxDraw->copySubBuffer == NULL)
- return __glXError(GLXBadDrawable);
-
- (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height);
-
- return Success;
-}
-
-/*
-** Get drawable attributes
-*/
-static int
-DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
-{
- ClientPtr client = cl->client;
- xGLXGetDrawableAttributesReply reply;
- __GLXdrawable *pGlxDraw;
- CARD32 attributes[6];
- int numAttribs, error;
-
- if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
- DixGetAttrAccess, &pGlxDraw, &error))
- return error;
-
- numAttribs = 3;
- reply.length = numAttribs << 1;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.numAttribs = numAttribs;
-
- attributes[0] = GLX_TEXTURE_TARGET_EXT;
- attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
- GLX_TEXTURE_RECTANGLE_EXT;
- attributes[2] = GLX_Y_INVERTED_EXT;
- attributes[3] = GL_FALSE;
- attributes[4] = GLX_EVENT_MASK;
- attributes[5] = pGlxDraw->eventMask;
-
- if (client->swapped) {
- __glXSwapGetDrawableAttributesReply(client, &reply, attributes);
- } else {
- WriteToClient(client, sz_xGLXGetDrawableAttributesReply,
- (char *)&reply);
- WriteToClient(client, reply.length * sizeof (CARD32),
- (char *)attributes);
- }
-
- return Success;
-}
-
-int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
-
- return DoGetDrawableAttributes(cl, req->drawable);
-}
-
-int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetDrawableAttributesSGIXReq *req =
- (xGLXGetDrawableAttributesSGIXReq *)pc;
-
- return DoGetDrawableAttributes(cl, req->drawable);
-}
-
-/************************************************************************/
-
-/*
-** Render and Renderlarge are not in the GLX API. They are used by the GLX
-** client library to send batches of GL rendering commands.
-*/
-
-/*
-** Execute all the drawing commands in a request.
-*/
-int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXRenderReq *req;
- ClientPtr client= cl->client;
- int left, cmdlen, error;
- int commandsDone;
- CARD16 opcode;
- __GLXrenderHeader *hdr;
- __GLXcontext *glxc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- req = (xGLXRenderReq *) pc;
- if (client->swapped) {
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- }
-
- glxc = __glXForceCurrent(cl, req->contextTag, &error);
- if (!glxc) {
- return error;
- }
-
- commandsDone = 0;
- pc += sz_xGLXRenderReq;
- left = (req->length << 2) - sz_xGLXRenderReq;
- while (left > 0) {
- __GLXrenderSizeData entry;
- int extra;
- __GLXdispatchRenderProcPtr proc;
- int err;
-
- /*
- ** Verify that the header length and the overall length agree.
- ** Also, each command must be word aligned.
- */
- hdr = (__GLXrenderHeader *) pc;
- if (client->swapped) {
- __GLX_SWAP_SHORT(&hdr->length);
- __GLX_SWAP_SHORT(&hdr->opcode);
- }
- cmdlen = hdr->length;
- opcode = hdr->opcode;
-
- /*
- ** Check for core opcodes and grab entry data.
- */
- err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
- proc = (__GLXdispatchRenderProcPtr)
- __glXGetProtocolDecodeFunction(& Render_dispatch_info,
- opcode, client->swapped);
-
- if ((err < 0) || (proc == NULL)) {
- client->errorValue = commandsDone;
- return __glXError(GLXBadRenderRequest);
- }
-
- if (entry.varsize) {
- /* variable size command */
- extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE,
- client->swapped);
- if (extra < 0) {
- extra = 0;
- }
- if (cmdlen != __GLX_PAD(entry.bytes + extra)) {
- return BadLength;
- }
- } else {
- /* constant size command */
- if (cmdlen != __GLX_PAD(entry.bytes)) {
- return BadLength;
- }
- }
- if (left < cmdlen) {
- return BadLength;
- }
-
- /*
- ** Skip over the header and execute the command. We allow the
- ** caller to trash the command memory. This is useful especially
- ** for things that require double alignment - they can just shift
- ** the data towards lower memory (trashing the header) by 4 bytes
- ** and achieve the required alignment.
- */
- (*proc)(pc + __GLX_RENDER_HDR_SIZE);
- pc += cmdlen;
- left -= cmdlen;
- commandsDone++;
- }
- __GLX_NOTE_UNFLUSHED_CMDS(glxc);
- return Success;
-}
-
-
-/*
-** Execute a large rendering request (one that spans multiple X requests).
-*/
-int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXRenderLargeReq *req;
- ClientPtr client= cl->client;
- size_t dataBytes;
- __GLXrenderLargeHeader *hdr;
- __GLXcontext *glxc;
- int error;
- CARD16 opcode;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- req = (xGLXRenderLargeReq *) pc;
- if (client->swapped) {
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(&req->dataBytes);
- __GLX_SWAP_SHORT(&req->requestNumber);
- __GLX_SWAP_SHORT(&req->requestTotal);
- }
-
- glxc = __glXForceCurrent(cl, req->contextTag, &error);
- if (!glxc) {
- /* Reset in case this isn't 1st request. */
- __glXResetLargeCommandStatus(cl);
- return error;
- }
- dataBytes = req->dataBytes;
-
- /*
- ** Check the request length.
- */
- if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) {
- client->errorValue = req->length;
- /* Reset in case this isn't 1st request. */
- __glXResetLargeCommandStatus(cl);
- return BadLength;
- }
- pc += sz_xGLXRenderLargeReq;
-
- if (cl->largeCmdRequestsSoFar == 0) {
- __GLXrenderSizeData entry;
- int extra;
- size_t cmdlen;
- int err;
-
- /*
- ** This is the first request of a multi request command.
- ** Make enough space in the buffer, then copy the entire request.
- */
- if (req->requestNumber != 1) {
- client->errorValue = req->requestNumber;
- return __glXError(GLXBadLargeRequest);
- }
-
- hdr = (__GLXrenderLargeHeader *) pc;
- if (client->swapped) {
- __GLX_SWAP_INT(&hdr->length);
- __GLX_SWAP_INT(&hdr->opcode);
- }
- cmdlen = hdr->length;
- opcode = hdr->opcode;
-
- /*
- ** Check for core opcodes and grab entry data.
- */
- err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
- if (err < 0) {
- client->errorValue = opcode;
- return __glXError(GLXBadLargeRequest);
- }
-
- if (entry.varsize) {
- /*
- ** If it's a variable-size command (a command whose length must
- ** be computed from its parameters), all the parameters needed
- ** will be in the 1st request, so it's okay to do this.
- */
- extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE,
- client->swapped);
- if (extra < 0) {
- extra = 0;
- }
- /* large command's header is 4 bytes longer, so add 4 */
- if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) {
- return BadLength;
- }
- } else {
- /* constant size command */
- if (cmdlen != __GLX_PAD(entry.bytes + 4)) {
- return BadLength;
- }
- }
- /*
- ** Make enough space in the buffer, then copy the entire request.
- */
- if (cl->largeCmdBufSize < cmdlen) {
- if (!cl->largeCmdBuf) {
- cl->largeCmdBuf = (GLbyte *) malloc(cmdlen);
- } else {
- cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, cmdlen);
- }
- if (!cl->largeCmdBuf) {
- return BadAlloc;
- }
- cl->largeCmdBufSize = cmdlen;
- }
- memcpy(cl->largeCmdBuf, pc, dataBytes);
-
- cl->largeCmdBytesSoFar = dataBytes;
- cl->largeCmdBytesTotal = cmdlen;
- cl->largeCmdRequestsSoFar = 1;
- cl->largeCmdRequestsTotal = req->requestTotal;
- return Success;
-
- } else {
- /*
- ** We are receiving subsequent (i.e. not the first) requests of a
- ** multi request command.
- */
-
- /*
- ** Check the request number and the total request count.
- */
- if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) {
- client->errorValue = req->requestNumber;
- __glXResetLargeCommandStatus(cl);
- return __glXError(GLXBadLargeRequest);
- }
- if (req->requestTotal != cl->largeCmdRequestsTotal) {
- client->errorValue = req->requestTotal;
- __glXResetLargeCommandStatus(cl);
- return __glXError(GLXBadLargeRequest);
- }
-
- /*
- ** Check that we didn't get too much data.
- */
- if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) {
- client->errorValue = dataBytes;
- __glXResetLargeCommandStatus(cl);
- return __glXError(GLXBadLargeRequest);
- }
- memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
- cl->largeCmdBytesSoFar += dataBytes;
- cl->largeCmdRequestsSoFar++;
-
- if (req->requestNumber == cl->largeCmdRequestsTotal) {
- __GLXdispatchRenderProcPtr proc;
-
- /*
- ** This is the last request; it must have enough bytes to complete
- ** the command.
- */
- /* NOTE: the two pad macros have been added below; they are needed
- ** because the client library pads the total byte count, but not
- ** the per-request byte counts. The Protocol Encoding says the
- ** total byte count should not be padded, so a proposal will be
- ** made to the ARB to relax the padding constraint on the total
- ** byte count, thus preserving backward compatibility. Meanwhile,
- ** the padding done below fixes a bug that did not allow
- ** large commands of odd sizes to be accepted by the server.
- */
- if (__GLX_PAD(cl->largeCmdBytesSoFar) !=
- __GLX_PAD(cl->largeCmdBytesTotal)) {
- client->errorValue = dataBytes;
- __glXResetLargeCommandStatus(cl);
- return __glXError(GLXBadLargeRequest);
- }
- hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf;
- /*
- ** The opcode and length field in the header had already been
- ** swapped when the first request was received.
- **
- ** Use the opcode to index into the procedure table.
- */
- opcode = hdr->opcode;
-
- proc = (__GLXdispatchRenderProcPtr)
- __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode,
- client->swapped);
- if (proc == NULL) {
- client->errorValue = opcode;
- return __glXError(GLXBadLargeRequest);
- }
-
- /*
- ** Skip over the header and execute the command.
- */
- (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
- __GLX_NOTE_UNFLUSHED_CMDS(glxc);
-
- /*
- ** Reset for the next RenderLarge series.
- */
- __glXResetLargeCommandStatus(cl);
- } else {
- /*
- ** This is neither the first nor the last request.
- */
- }
- return Success;
- }
-}
-
-/************************************************************************/
-
-/*
-** No support is provided for the vendor-private requests other than
-** allocating the entry points in the dispatch table.
-*/
-
-int __glXDisp_VendorPrivate(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- GLint vendorcode = req->vendorCode;
- __GLXdispatchVendorPrivProcPtr proc;
-
-
- proc = (__GLXdispatchVendorPrivProcPtr)
- __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
- vendorcode, 0);
- if (proc != NULL) {
- (*proc)(cl, (GLbyte*)req);
- return Success;
- }
-
- cl->client->errorValue = req->vendorCode;
- return __glXError(GLXUnsupportedPrivateRequest);
-}
-
-int __glXDisp_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- GLint vendorcode = req->vendorCode;
- __GLXdispatchVendorPrivProcPtr proc;
-
-
- proc = (__GLXdispatchVendorPrivProcPtr)
- __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
- vendorcode, 0);
- if (proc != NULL) {
- return (*proc)(cl, (GLbyte*)req);
- }
-
- cl->client->errorValue = vendorcode;
- return __glXError(GLXUnsupportedPrivateRequest);
-}
-
-int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
- xGLXQueryExtensionsStringReply reply;
- __GLXscreen *pGlxScreen;
- size_t n, length;
- char *buf;
- int err;
-
- if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
- return err;
-
- n = strlen(pGlxScreen->GLXextensions) + 1;
- length = __GLX_PAD(n) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = length;
- reply.n = n;
-
- /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/
- buf = (char *) malloc(length << 2);
- if (buf == NULL)
- return BadAlloc;
- memcpy(buf, pGlxScreen->GLXextensions, n);
-
- if (client->swapped) {
- glxSwapQueryExtensionsStringReply(client, &reply, buf);
- } else {
- WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
- WriteToClient(client, (int)(length << 2), (char *)buf);
- }
-
- free(buf);
- return Success;
-}
-
-int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
- xGLXQueryServerStringReply reply;
- size_t n, length;
- const char *ptr;
- char *buf;
- __GLXscreen *pGlxScreen;
- int err;
- char ver_str[16];
-
- if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
- return err;
-
- switch(req->name) {
- case GLX_VENDOR:
- ptr = pGlxScreen->GLXvendor;
- break;
- case GLX_VERSION:
- /* Return to the server version rather than the screen version
- * to prevent confusion when they do not match.
- */
- snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion);
- ptr = ver_str;
- break;
- case GLX_EXTENSIONS:
- ptr = pGlxScreen->GLXextensions;
- break;
- default:
- return BadValue;
- }
-
- n = strlen(ptr) + 1;
- length = __GLX_PAD(n) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = length;
- reply.n = n;
-
- buf = (char *) malloc(length << 2);
- if (buf == NULL) {
- return BadAlloc;
- }
- memcpy(buf, ptr, n);
-
- if (client->swapped) {
- glxSwapQueryServerStringReply(client, &reply, buf);
- } else {
- WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
- WriteToClient(client, (int)(length << 2), buf);
- }
-
- free(buf);
- return Success;
-}
-
-int __glXDisp_ClientInfo(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
- const char *buf;
-
- cl->GLClientmajorVersion = req->major;
- cl->GLClientminorVersion = req->minor;
- free(cl->GLClientextensions);
- buf = (const char *)(req+1);
- cl->GLClientextensions = strdup(buf);
-
- return Success;
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> +#include <assert.h> + +#include "glxserver.h" +#include <GL/glxtokens.h> +#include <unpack.h> +#include <pixmapstr.h> +#include <windowstr.h> +#include "glxutil.h" +#include "glxext.h" +#include "glapitable.h" +#include "glapi.h" +#include "glthread.h" +#include "dispatch.h" +#include "indirect_dispatch.h" +#include "indirect_table.h" +#include "indirect_util.h" + +static int +validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) +{ + /* + ** Check if screen exists. + */ + if (screen < 0 || screen >= screenInfo.numScreens) { + client->errorValue = screen; + *err = BadValue; + return FALSE; + } + *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); + + return TRUE; +} + +static int +validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, + __GLXconfig **config, int *err) +{ + __GLXconfig *m; + + for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) + if (m->fbconfigID == id) { + *config = m; + return TRUE; + } + + client->errorValue = id; + *err = __glXError(GLXBadFBConfig); + + return FALSE; +} + +static int +validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, + __GLXconfig **config, int *err) +{ + int i; + + for (i = 0; i < pGlxScreen->numVisuals; i++) + if (pGlxScreen->visuals[i]->visualID == id) { + *config = pGlxScreen->visuals[i]; + return TRUE; + } + + client->errorValue = id; + *err = BadValue; + + return FALSE; +} + +static int +validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config, + DrawablePtr pDraw, int *err) +{ + ScreenPtr pScreen = pDraw->pScreen; + VisualPtr pVisual = NULL; + XID vid; + int i; + + vid = wVisual((WindowPtr)pDraw); + for (i = 0; i < pScreen->numVisuals; i++) { + if (pScreen->visuals[i].vid == vid) { + pVisual = &pScreen->visuals[i]; + break; + } + } + + /* FIXME: What exactly should we check here... */ + if (pVisual->class != glxConvertToXVisualType(config->visualType) || + !(config->drawableType & GLX_WINDOW_BIT)) { + client->errorValue = pDraw->id; + *err = BadMatch; + return FALSE; + } + + return TRUE; +} + +static int +validGlxContext(ClientPtr client, XID id, int access_mode, + __GLXcontext **context, int *err) +{ + *err = dixLookupResourceByType((pointer *) context, id, + __glXContextRes, client, access_mode); + if (*err != Success) { + client->errorValue = id; + if (*err == BadValue) + *err = __glXError(GLXBadContext); + return FALSE; + } + + return TRUE; +} + +static int +validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, + __GLXdrawable **drawable, int *err) +{ + int rc; + + rc = dixLookupResourceByType((pointer *) drawable, id, + __glXDrawableRes, client, access_mode); + if (rc != Success && rc != BadValue) { + *err = rc; + client->errorValue = id; + return FALSE; + } + + /* If the ID of the glx drawable we looked up doesn't match the id + * we looked for, it's because we looked it up under the X + * drawable ID (see DoCreateGLXDrawable). */ + if (rc == BadValue || + (*drawable)->drawId != id || + (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) { + client->errorValue = id; + switch (type) { + case GLX_DRAWABLE_WINDOW: + *err = __glXError(GLXBadWindow); + return FALSE; + case GLX_DRAWABLE_PIXMAP: + *err = __glXError(GLXBadPixmap); + return FALSE; + case GLX_DRAWABLE_PBUFFER: + *err = __glXError(GLXBadPbuffer); + return FALSE; + case GLX_DRAWABLE_ANY: + *err = __glXError(GLXBadDrawable); + return FALSE; + } + } + + return TRUE; +} + +void +__glXContextDestroy(__GLXcontext *context) +{ + __glXFlushContextCache(); +} + +static void __glXdirectContextDestroy(__GLXcontext *context) +{ + __glXContextDestroy(context); + free(context); +} + +static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, + __GLXconfig *modes, + __GLXcontext *shareContext) +{ + __GLXcontext *context; + + context = calloc(1, sizeof (__GLXcontext)); + if (context == NULL) + return NULL; + + context->destroy = __glXdirectContextDestroy; + + return context; +} + +/** + * Create a GL context with the given properties. This routine is used + * to implement \c glXCreateContext, \c glXCreateNewContext, and + * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way + * that GLXFBConfigs are implemented. Basically, the FBConfigID is the + * same as the VisualID. + */ + +static int +DoCreateContext(__GLXclientState *cl, GLXContextID gcId, + GLXContextID shareList, __GLXconfig *config, + __GLXscreen *pGlxScreen, GLboolean isDirect) +{ + ClientPtr client = cl->client; + __GLXcontext *glxc, *shareglxc; + int err; + + LEGAL_NEW_RESOURCE(gcId, client); + + /* + ** Find the display list space that we want to share. + ** + ** NOTE: In a multithreaded X server, we would need to keep a reference + ** count for each display list so that if one client detroyed a list that + ** another client was using, the list would not really be freed until it + ** was no longer in use. Since this sample implementation has no support + ** for multithreaded servers, we don't do this. + */ + if (shareList == None) { + shareglxc = 0; + } else { + if (!validGlxContext(client, shareList, DixReadAccess, + &shareglxc, &err)) + return err; + + if (shareglxc->isDirect) { + /* + ** NOTE: no support for sharing display lists between direct + ** contexts, even if they are in the same address space. + */ +#if 0 + /* Disabling this code seems to allow shared display lists + * and texture objects to work. We'll leave it disabled for now. + */ + client->errorValue = shareList; + return BadMatch; +#endif + } else { + /* + ** Create an indirect context regardless of what the client asked + ** for; this way we can share display list space with shareList. + */ + isDirect = GL_FALSE; + } + } + + /* + ** Allocate memory for the new context + */ + if (!isDirect) + glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc); + else + glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc); + if (!glxc) { + return BadAlloc; + } + + /* + ** Initially, setup the part of the context that could be used by + ** a GL core that needs windowing information (e.g., Mesa). + */ + glxc->pGlxScreen = pGlxScreen; + glxc->config = config; + + /* + ** Register this context as a resource. + */ + if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { + (*glxc->destroy)(glxc); + client->errorValue = gcId; + return BadAlloc; + } + + /* + ** Finally, now that everything is working, setup the rest of the + ** context. + */ + glxc->id = gcId; + glxc->share_id = shareList; + glxc->idExists = GL_TRUE; + glxc->isCurrent = GL_FALSE; + glxc->isDirect = isDirect; + glxc->renderMode = GL_RENDER; + + __glXAddToContextList(glxc); + + return Success; +} + +int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; + __GLXconfig *config; + __GLXscreen *pGlxScreen; + int err; + + REQUEST_SIZE_MATCH(xGLXCreateContextReq); + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} + +int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; + __GLXconfig *config; + __GLXscreen *pGlxScreen; + int err; + + REQUEST_SIZE_MATCH(xGLXCreateNewContextReq); + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} + +int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateContextWithConfigSGIXReq *req = + (xGLXCreateContextWithConfigSGIXReq *) pc; + __GLXconfig *config; + __GLXscreen *pGlxScreen; + int err; + + REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq); + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} +int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; + __GLXcontext *glxc; + int err; + + REQUEST_SIZE_MATCH(xGLXDestroyContextReq); + + if (!validGlxContext(cl->client, req->context, DixDestroyAccess, + &glxc, &err)) + return err; + + FreeResourceByType(req->context, __glXContextRes, FALSE); + return Success; +} + +/*****************************************************************************/ + +/* +** For each client, the server keeps a table of all the contexts that are +** current for that client (each thread of a client may have its own current +** context). These routines add, change, and lookup contexts in the table. +*/ + +/* +** Add a current context, and return the tag that will be used to refer to it. +*/ +static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc) +{ + int i; + int num = cl->numCurrentContexts; + __GLXcontext **table = cl->currentContexts; + + if (!glxc) return -1; + + /* + ** Try to find an empty slot and use it. + */ + for (i=0; i < num; i++) { + if (!table[i]) { + table[i] = glxc; + return i+1; + } + } + /* + ** Didn't find a free slot, so we'll have to grow the table. + */ + if (!num) { + table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); + } else { + table = (__GLXcontext **) realloc(table, + (num+1)*sizeof(__GLXcontext *)); + } + table[num] = glxc; + cl->currentContexts = table; + cl->numCurrentContexts++; + return num+1; +} + +/* +** Given a tag, change the current context for the corresponding entry. +*/ +static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, + GLXContextTag tag) +{ + __GLXcontext **table = cl->currentContexts; + table[tag-1] = glxc; +} + +/* +** For this implementation we have chosen to simply use the index of the +** context's entry in the table as the context tag. A tag must be greater +** than 0. +*/ +__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) +{ + int num = cl->numCurrentContexts; + + if (tag < 1 || tag > num) { + return 0; + } else { + return cl->currentContexts[tag-1]; + } +} + +/*****************************************************************************/ + +static void StopUsingContext(__GLXcontext *glxc) +{ + if (glxc) { + if (glxc == __glXLastContext) { + /* Tell server GL library */ + __glXLastContext = 0; + } + glxc->isCurrent = GL_FALSE; + if (!glxc->idExists) { + __glXFreeContext(glxc); + } + } +} + +static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) +{ + glxc->isCurrent = GL_TRUE; + __glXLastContext = glxc; +} + +/** + * This is a helper function to handle the legacy (pre GLX 1.3) cases + * where passing an X window to glXMakeCurrent is valid. Given a + * resource ID, look up the GLX drawable if available, otherwise, make + * sure it's an X window and create a GLX drawable one the fly. + */ +static __GLXdrawable * +__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, + int *error) +{ + DrawablePtr pDraw; + __GLXdrawable *pGlxDraw; + int rc; + + if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, + DixWriteAccess, &pGlxDraw, &rc)) { + if (glxc != NULL && pGlxDraw->config != glxc->config) { + client->errorValue = drawId; + *error = BadMatch; + return NULL; + } + + return pGlxDraw; + } + + /* No active context and an unknown drawable, bail. */ + if (glxc == NULL) { + client->errorValue = drawId; + *error = BadMatch; + return NULL; + } + + /* The drawId wasn't a GLX drawable. Make sure it's a window and + * create a GLXWindow for it. Check that the drawable screen + * matches the context screen and that the context fbconfig is + * compatible with the window visual. */ + + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); + if (rc != Success || pDraw->type != DRAWABLE_WINDOW) { + client->errorValue = drawId; + *error = __glXError(GLXBadDrawable); + return NULL; + } + + if (pDraw->pScreen != glxc->pGlxScreen->pScreen) { + client->errorValue = pDraw->pScreen->myNum; + *error = BadMatch; + return NULL; + } + + if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) + return NULL; + + pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen, + pDraw, drawId, + GLX_DRAWABLE_WINDOW, + drawId, glxc->config); + + /* since we are creating the drawablePrivate, drawId should be new */ + if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { + pGlxDraw->destroy (pGlxDraw); + *error = BadAlloc; + return NULL; + } + + return pGlxDraw; +} + +/*****************************************************************************/ +/* +** Make an OpenGL context and drawable current. +*/ + +static int +DoMakeCurrent(__GLXclientState *cl, + GLXDrawable drawId, GLXDrawable readId, + GLXContextID contextId, GLXContextTag tag) +{ + ClientPtr client = cl->client; + xGLXMakeCurrentReply reply; + __GLXcontext *glxc, *prevglxc; + __GLXdrawable *drawPriv = NULL; + __GLXdrawable *readPriv = NULL; + int error; + GLuint mask; + + /* + ** If one is None and the other isn't, it's a bad match. + */ + + mask = (drawId == None) ? (1 << 0) : 0; + mask |= (readId == None) ? (1 << 1) : 0; + mask |= (contextId == None) ? (1 << 2) : 0; + + if ( (mask != 0x00) && (mask != 0x07) ) { + return BadMatch; + } + + /* + ** Lookup old context. If we have one, it must be in a usable state. + */ + if (tag != 0) { + prevglxc = __glXLookupContextByTag(cl, tag); + if (!prevglxc) { + /* + ** Tag for previous context is invalid. + */ + return __glXError(GLXBadContextTag); + } + if (prevglxc->renderMode != GL_RENDER) { + /* Oops. Not in render mode render. */ + client->errorValue = prevglxc->id; + return __glXError(GLXBadContextState); + } + } else { + prevglxc = 0; + } + + /* + ** Lookup new context. It must not be current for someone else. + */ + if (contextId != None) { + int status; + + if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error)) + return error; + if ((glxc != prevglxc) && glxc->isCurrent) { + /* Context is current to somebody else */ + return BadAccess; + } + + assert( drawId != None ); + assert( readId != None ); + + drawPriv = __glXGetDrawable(glxc, drawId, client, &status); + if (drawPriv == NULL) + return status; + + readPriv = __glXGetDrawable(glxc, readId, client, &status); + if (readPriv == NULL) + return status; + + } else { + /* Switching to no context. Ignore new drawable. */ + glxc = 0; + drawPriv = 0; + readPriv = 0; + } + + + if (prevglxc) { + /* + ** Flush the previous context if needed. + */ + if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) { + if (__glXForceCurrent(cl, tag, (int *)&error)) { + CALL_Flush( GET_DISPATCH(), () ); + __GLX_NOTE_FLUSHED_CMDS(prevglxc); + } else { + return error; + } + } + + /* + ** Make the previous context not current. + */ + if (!(*prevglxc->loseCurrent)(prevglxc)) { + return __glXError(GLXBadContext); + } + __glXFlushContextCache(); + if (!prevglxc->isDirect) { + prevglxc->drawPriv = NULL; + prevglxc->readPriv = NULL; + } + } + + + if ((glxc != 0) && !glxc->isDirect) { + + glxc->drawPriv = drawPriv; + glxc->readPriv = readPriv; + + /* make the context current */ + if (!(*glxc->makeCurrent)(glxc)) { + glxc->drawPriv = NULL; + glxc->readPriv = NULL; + return __glXError(GLXBadContext); + } + + glxc->isCurrent = GL_TRUE; + } + + if (prevglxc) { + ChangeCurrentContext(cl, glxc, tag); + StopUsingContext(prevglxc); + } else { + tag = AddCurrentContext(cl, glxc); + } + + if (glxc) { + StartUsingContext(cl, glxc); + reply.contextTag = tag; + } else { + reply.contextTag = 0; + } + + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __glXSwapMakeCurrentReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)&reply); + } + return Success; +} + +int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; + + REQUEST_SIZE_MATCH(xGLXMakeCurrentReq); + + return DoMakeCurrent( cl, req->drawable, req->drawable, + req->context, req->oldContextTag ); +} + +int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; + + REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq); + + return DoMakeCurrent( cl, req->drawable, req->readdrawable, + req->context, req->oldContextTag ); +} + +int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; + + REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq); + + return DoMakeCurrent( cl, req->drawable, req->readable, + req->context, req->oldContextTag ); +} + +int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; + xGLXIsDirectReply reply; + __GLXcontext *glxc; + int err; + + REQUEST_SIZE_MATCH(xGLXIsDirectReq); + + if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err)) + return err; + + reply.isDirect = glxc->isDirect; + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __glXSwapIsDirectReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); + } + + return Success; +} + +int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; + xGLXQueryVersionReply reply; + GLuint major, minor; + + REQUEST_SIZE_MATCH(xGLXQueryVersionReq); + + major = req->majorVersion; + minor = req->minorVersion; + (void)major; + (void)minor; + + /* + ** Server should take into consideration the version numbers sent by the + ** client if it wants to work with older clients; however, in this + ** implementation the server just returns its version number. + */ + reply.majorVersion = glxMajorVersion; + reply.minorVersion = glxMinorVersion; + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __glXSwapQueryVersionReply(client, &reply); + } else { + WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); + } + return Success; +} + +int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; + GLXContextTag tag; + __GLXcontext *glxc = NULL; + int error; + + REQUEST_SIZE_MATCH(xGLXWaitGLReq); + + tag = req->contextTag; + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) + return __glXError(GLXBadContextTag); + + if (!__glXForceCurrent(cl, req->contextTag, &error)) + return error; + + CALL_Finish( GET_DISPATCH(), () ); + } + + if (glxc && glxc->drawPriv->waitGL) + (*glxc->drawPriv->waitGL)(glxc->drawPriv); + + return Success; +} + +int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXWaitXReq *req = (xGLXWaitXReq *)pc; + GLXContextTag tag; + __GLXcontext *glxc = NULL; + int error; + + REQUEST_SIZE_MATCH(xGLXWaitXReq); + + tag = req->contextTag; + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) + return __glXError(GLXBadContextTag); + + if (!__glXForceCurrent(cl, req->contextTag, &error)) + return error; + } + + if (glxc && glxc->drawPriv->waitX) + (*glxc->drawPriv->waitX)(glxc->drawPriv); + + return Success; +} + +int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; + GLXContextID source; + GLXContextID dest; + GLXContextTag tag; + unsigned long mask; + __GLXcontext *src, *dst; + int error; + + REQUEST_SIZE_MATCH(xGLXCopyContextReq); + + source = req->source; + dest = req->dest; + tag = req->contextTag; + mask = req->mask; + if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error)) + return error; + if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error)) + return error; + + /* + ** They must be in the same address space, and same screen. + ** NOTE: no support for direct rendering contexts here. + */ + if (src->isDirect || dst->isDirect || + (src->pGlxScreen != dst->pGlxScreen)) { + client->errorValue = source; + return BadMatch; + } + + /* + ** The destination context must not be current for any client. + */ + if (dst->isCurrent) { + client->errorValue = dest; + return BadAccess; + } + + if (tag) { + __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); + + if (!tagcx) { + return __glXError(GLXBadContextTag); + } + if (tagcx != src) { + /* + ** This would be caused by a faulty implementation of the client + ** library. + */ + return BadMatch; + } + /* + ** In this case, glXCopyContext is in both GL and X streams, in terms + ** of sequentiality. + */ + if (__glXForceCurrent(cl, tag, &error)) { + /* + ** Do whatever is needed to make sure that all preceding requests + ** in both streams are completed before the copy is executed. + */ + CALL_Finish( GET_DISPATCH(), () ); + __GLX_NOTE_FLUSHED_CMDS(tagcx); + } else { + return error; + } + } + /* + ** Issue copy. The only reason for failure is a bad mask. + */ + if (!(*dst->copy)(dst, src, mask)) { + client->errorValue = mask; + return BadValue; + } + return Success; +} + +enum { + GLX_VIS_CONFIG_UNPAIRED = 18, + GLX_VIS_CONFIG_PAIRED = 20 +}; + +enum { + GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED +}; + +int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; + ClientPtr client = cl->client; + xGLXGetVisualConfigsReply reply; + __GLXscreen *pGlxScreen; + __GLXconfig *modes; + CARD32 buf[GLX_VIS_CONFIG_TOTAL]; + int p, i, err; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq); + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + + reply.numVisuals = pGlxScreen->numVisuals; + reply.numProps = GLX_VIS_CONFIG_TOTAL; + reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + __GLX_SWAP_INT(&reply.numVisuals); + __GLX_SWAP_INT(&reply.numProps); + } + + WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); + + for (i = 0; i < pGlxScreen->numVisuals; i++) { + modes = pGlxScreen->visuals[i]; + + p = 0; + buf[p++] = modes->visualID; + buf[p++] = glxConvertToXVisualType( modes->visualType ); + buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE; + + buf[p++] = modes->redBits; + buf[p++] = modes->greenBits; + buf[p++] = modes->blueBits; + buf[p++] = modes->alphaBits; + buf[p++] = modes->accumRedBits; + buf[p++] = modes->accumGreenBits; + buf[p++] = modes->accumBlueBits; + buf[p++] = modes->accumAlphaBits; + + buf[p++] = modes->doubleBufferMode; + buf[p++] = modes->stereoMode; + + buf[p++] = modes->rgbBits; + buf[p++] = modes->depthBits; + buf[p++] = modes->stencilBits; + buf[p++] = modes->numAuxBuffers; + buf[p++] = modes->level; + + assert(p == GLX_VIS_CONFIG_UNPAIRED); + /* + ** Add token/value pairs for extensions. + */ + buf[p++] = GLX_VISUAL_CAVEAT_EXT; + buf[p++] = modes->visualRating; + buf[p++] = GLX_TRANSPARENT_TYPE; + buf[p++] = modes->transparentPixel; + buf[p++] = GLX_TRANSPARENT_RED_VALUE; + buf[p++] = modes->transparentRed; + buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; + buf[p++] = modes->transparentGreen; + buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; + buf[p++] = modes->transparentBlue; + buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; + buf[p++] = modes->transparentAlpha; + buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; + buf[p++] = modes->transparentIndex; + buf[p++] = GLX_SAMPLES_SGIS; + buf[p++] = modes->samples; + buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; + buf[p++] = modes->sampleBuffers; + buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */ + buf[p++] = 0; + + assert(p == GLX_VIS_CONFIG_TOTAL); + if (client->swapped) { + __GLX_SWAP_INT_ARRAY(buf, p); + } + WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf); + } + return Success; +} + +#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36) +#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) +/** + * Send the set of GLXFBConfigs to the client. There is not currently + * and interface into the driver on the server-side to get GLXFBConfigs, + * so we "invent" some based on the \c __GLXvisualConfig structures that + * the driver does supply. + * + * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX + * is the same, so this routine pulls double duty. + */ + +static int +DoGetFBConfigs(__GLXclientState *cl, unsigned screen) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsReply reply; + __GLXscreen *pGlxScreen; + CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; + int p, err; + __GLXconfig *modes; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err)) + return err; + + reply.numFBConfigs = pGlxScreen->numFBConfigs; + reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS; + reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if (client->swapped) { + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + __GLX_SWAP_INT(&reply.numFBConfigs); + __GLX_SWAP_INT(&reply.numAttribs); + } + + WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); + + for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) { + p = 0; + +#define WRITE_PAIR(tag,value) \ + do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) + + WRITE_PAIR( GLX_VISUAL_ID, modes->visualID ); + WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID ); + WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE ); + + WRITE_PAIR( GLX_RGBA, + (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE ); + WRITE_PAIR( GLX_RENDER_TYPE, modes->renderType ); + WRITE_PAIR( GLX_DOUBLEBUFFER, modes->doubleBufferMode ); + WRITE_PAIR( GLX_STEREO, modes->stereoMode ); + + WRITE_PAIR( GLX_BUFFER_SIZE, modes->rgbBits ); + WRITE_PAIR( GLX_LEVEL, modes->level ); + WRITE_PAIR( GLX_AUX_BUFFERS, modes->numAuxBuffers ); + WRITE_PAIR( GLX_RED_SIZE, modes->redBits ); + WRITE_PAIR( GLX_GREEN_SIZE, modes->greenBits ); + WRITE_PAIR( GLX_BLUE_SIZE, modes->blueBits ); + WRITE_PAIR( GLX_ALPHA_SIZE, modes->alphaBits ); + WRITE_PAIR( GLX_ACCUM_RED_SIZE, modes->accumRedBits ); + WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits ); + WRITE_PAIR( GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits ); + WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits ); + WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits ); + WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits ); + WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType ); + WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating ); + WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel ); + WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed ); + WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen ); + WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue ); + WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha ); + WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex ); + WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod ); + WRITE_PAIR( GLX_SAMPLES_SGIS, modes->samples ); + WRITE_PAIR( GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers ); + /* GLX_VISUAL_SELECT_GROUP_SGIX ? */ + WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba ); + WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets ); + + if (client->swapped) { + __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); + } + WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH, + (char *)buf); + } + return Success; +} + + +int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; + REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq); + return DoGetFBConfigs(cl, req->screen); +} + +int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; + REQUEST_SIZE_MATCH(xGLXGetFBConfigsSGIXReq); + return DoGetFBConfigs(cl, req->screen); +} + +GLboolean +__glXDrawableInit(__GLXdrawable *drawable, + __GLXscreen *screen, DrawablePtr pDraw, int type, + XID drawId, __GLXconfig *config) +{ + drawable->pDraw = pDraw; + drawable->type = type; + drawable->drawId = drawId; + drawable->config = config; + drawable->eventMask = 0; + + return GL_TRUE; +} + +void +__glXDrawableRelease(__GLXdrawable *drawable) +{ +} + +static int +DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, + __GLXconfig *config, DrawablePtr pDraw, XID drawableId, + XID glxDrawableId, int type) +{ + __GLXdrawable *pGlxDraw; + + if (pGlxScreen->pScreen != pDraw->pScreen) + return BadMatch; + + pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, + drawableId, type, + glxDrawableId, config); + if (pGlxDraw == NULL) + return BadAlloc; + + if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) { + pGlxDraw->destroy (pGlxDraw); + return BadAlloc; + } + + /* Add the glx drawable under the XID of the underlying X drawable + * too. That way we'll get a callback in DrawableGone and can + * clean up properly when the drawable is destroyed. */ + if (drawableId != glxDrawableId && + !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { + pGlxDraw->destroy (pGlxDraw); + return BadAlloc; + } + + return Success; +} + +static int +DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, + XID drawableId, XID glxDrawableId) +{ + DrawablePtr pDraw; + int err; + + LEGAL_NEW_RESOURCE(glxDrawableId, client); + + err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); + if (err != Success) { + client->errorValue = drawableId; + return err; + } + if (pDraw->type != DRAWABLE_PIXMAP) { + client->errorValue = drawableId; + return BadPixmap; + } + + err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId, + glxDrawableId, GLX_DRAWABLE_PIXMAP); + + return err; +} + +static void +determineTextureTarget(ClientPtr client, XID glxDrawableID, + CARD32 *attribs, CARD32 numAttribs) +{ + GLenum target = 0; + GLenum format = 0; + int i, err; + __GLXdrawable *pGlxDraw; + + if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP, + DixWriteAccess, &pGlxDraw, &err)) + /* We just added it in CreatePixmap, so we should never get here. */ + return; + + for (i = 0; i < numAttribs; i++) { + if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { + switch (attribs[2 * i + 1]) { + case GLX_TEXTURE_2D_EXT: + target = GL_TEXTURE_2D; + break; + case GLX_TEXTURE_RECTANGLE_EXT: + target = GL_TEXTURE_RECTANGLE_ARB; + break; + } + } + + if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT) + format = attribs[2 * i + 1]; + } + + if (!target) { + int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height; + + if (h & (h - 1) || w & (w - 1)) + target = GL_TEXTURE_RECTANGLE_ARB; + else + target = GL_TEXTURE_2D; + } + + pGlxDraw->target = target; + pGlxDraw->format = format; +} + +int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + __GLXconfig *config; + __GLXscreen *pGlxScreen; + int err; + + REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq); + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) + return err; + + return DoCreateGLXPixmap(cl->client, pGlxScreen, config, + req->pixmap, req->glxpixmap); +} + +int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + __GLXconfig *config; + __GLXscreen *pGlxScreen; + int err; + + REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq); + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3); + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + err = DoCreateGLXPixmap(cl->client, pGlxScreen, config, + req->pixmap, req->glxpixmap); + if (err != Success) + return err; + + determineTextureTarget(cl->client, req->glxpixmap, + (CARD32*) (req + 1), req->numAttribs); + + return Success; +} + +int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPixmapWithConfigSGIXReq *req = + (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; + __GLXconfig *config; + __GLXscreen *pGlxScreen; + int err; + + REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq); + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateGLXPixmap(cl->client, pGlxScreen, + config, req->pixmap, req->glxpixmap); +} + + +static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type) +{ + __GLXdrawable *pGlxDraw; + int err; + + if (!validGlxDrawable(cl->client, glxdrawable, type, + DixDestroyAccess, &pGlxDraw, &err)) + return err; + + FreeResource(glxdrawable, FALSE); + + return Success; +} + +int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; + + REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq); + + return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); +} + +int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc; + + REQUEST_SIZE_MATCH(xGLXDestroyPixmapReq); + + return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); +} + +static int +DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, + int width, int height, XID glxDrawableId) +{ + __GLXconfig *config; + __GLXscreen *pGlxScreen; + PixmapPtr pPixmap; + int err; + + LEGAL_NEW_RESOURCE(glxDrawableId, client); + + if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) + return err; + + __glXenterServer(GL_FALSE); + pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen, + width, height, config->rgbBits, 0); + __glXleaveServer(GL_FALSE); + + /* Assign the pixmap the same id as the pbuffer and add it as a + * resource so it and the DRI2 drawable will be reclaimed when the + * pbuffer is destroyed. */ + pPixmap->drawable.id = glxDrawableId; + if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap)) + return BadAlloc; + + return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, + glxDrawableId, glxDrawableId, + GLX_DRAWABLE_PBUFFER); +} + +int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc; + CARD32 *attrs; + int width, height, i; + + REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq); + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3); + + attrs = (CARD32 *) (req + 1); + width = 0; + height = 0; + + for (i = 0; i < req->numAttribs; i++) { + switch (attrs[i * 2]) { + case GLX_PBUFFER_WIDTH: + width = attrs[i * 2 + 1]; + break; + case GLX_PBUFFER_HEIGHT: + height = attrs[i * 2 + 1]; + break; + case GLX_LARGEST_PBUFFER: + case GLX_PRESERVED_CONTENTS: + /* FIXME: huh... */ + break; + } + } + + return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, + width, height, req->pbuffer); +} + +int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc; + + REQUEST_SIZE_MATCH(xGLXCreateGLXPbufferSGIXReq); + + return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, + req->width, req->height, req->pbuffer); +} + +int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; + + REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq); + + return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); +} + +int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; + + REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq); + + return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); +} + +static int +DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable, + int numAttribs, CARD32 *attribs) +{ + __GLXdrawable *pGlxDraw; + int i, err; + + if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY, + DixSetAttrAccess, &pGlxDraw, &err)) + return err; + + for (i = 0; i < numAttribs; i++) { + switch(attribs[i * 2]) { + case GLX_EVENT_MASK: + /* All we do is to record the event mask so we can send it + * back when queried. We never actually clobber the + * pbuffers, so we never need to send out the event. */ + pGlxDraw->eventMask = attribs[i * 2 + 1]; + break; + } + } + + return Success; +} + +int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXChangeDrawableAttributesReq *req = + (xGLXChangeDrawableAttributesReq *) pc; + + REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq); + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3); + + return DoChangeDrawableAttributes(cl->client, req->drawable, + req->numAttribs, (CARD32 *) (req + 1)); +} + +int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXChangeDrawableAttributesSGIXReq *req = + (xGLXChangeDrawableAttributesSGIXReq *)pc; + + REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq); + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3); + + return DoChangeDrawableAttributes(cl->client, req->drawable, + req->numAttribs, (CARD32 *) (req + 1)); +} + +int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; + __GLXconfig *config; + __GLXscreen *pGlxScreen; + ClientPtr client = cl->client; + DrawablePtr pDraw; + int err; + + REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq); + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3); + + LEGAL_NEW_RESOURCE(req->glxwindow, client); + + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess); + if (err != Success || pDraw->type != DRAWABLE_WINDOW) { + client->errorValue = req->window; + return BadWindow; + } + + if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) + return err; + + return DoCreateGLXDrawable(client, pGlxScreen, config, + pDraw, req->window, + req->glxwindow, GLX_DRAWABLE_WINDOW); +} + +int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; + + REQUEST_SIZE_MATCH(xGLXDestroyWindowReq); + + return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW); +} + + +/*****************************************************************************/ + +/* +** NOTE: There is no portable implementation for swap buffers as of +** this time that is of value. Consequently, this code must be +** implemented by somebody other than SGI. +*/ +int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; + GLXContextTag tag; + XID drawId; + __GLXcontext *glxc = NULL; + __GLXdrawable *pGlxDraw; + int error; + + REQUEST_SIZE_MATCH(xGLXSwapBuffersReq); + + tag = req->contextTag; + drawId = req->drawable; + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXError(GLXBadContextTag); + } + /* + ** The calling thread is swapping its current drawable. In this case, + ** glxSwapBuffers is in both GL and X streams, in terms of + ** sequentiality. + */ + if (__glXForceCurrent(cl, tag, &error)) { + /* + ** Do whatever is needed to make sure that all preceding requests + ** in both streams are completed before the swap is executed. + */ + CALL_Finish( GET_DISPATCH(), () ); + __GLX_NOTE_FLUSHED_CMDS(glxc); + } else { + return error; + } + } + + pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); + if (pGlxDraw == NULL) + return error; + + if (pGlxDraw->type == DRAWABLE_WINDOW && + (*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE) + return __glXError(GLXBadDrawable); + + return Success; +} + + +static int +DoQueryContext(__GLXclientState *cl, GLXContextID gcId) +{ + ClientPtr client = cl->client; + __GLXcontext *ctx; + xGLXQueryContextInfoEXTReply reply; + int nProps; + int *sendBuf, *pSendBuf; + int nReplyBytes; + int err; + + if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err)) + return err; + + nProps = 3; + reply.length = nProps << 1; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.n = nProps; + + nReplyBytes = reply.length << 2; + sendBuf = (int *)malloc((size_t)nReplyBytes); + if (sendBuf == NULL) { + return __glXError(GLXBadContext); /* XXX: Is this correct? */ + } + pSendBuf = sendBuf; + *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; + *pSendBuf++ = (int)(ctx->share_id); + *pSendBuf++ = GLX_VISUAL_ID_EXT; + *pSendBuf++ = (int)(ctx->config->visualID); + *pSendBuf++ = GLX_SCREEN_EXT; + *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum); + + if (client->swapped) { + __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); + } else { + WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); + WriteToClient(client, nReplyBytes, (char *)sendBuf); + } + free((char *)sendBuf); + + return Success; +} + +int __glXDisp_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; + + REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq); + + return DoQueryContext(cl, req->context); +} + +int __glXDisp_QueryContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc; + + REQUEST_SIZE_MATCH(xGLXQueryContextReq); + + return DoQueryContext(cl, req->context); +} + +int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + ClientPtr client = cl->client; + __GLXcontext *context; + __GLXdrawable *pGlxDraw; + GLXDrawable drawId; + int buffer; + int error; + + REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); + + pc += __GLX_VENDPRIV_HDR_SIZE; + + drawId = *((CARD32 *) (pc)); + buffer = *((INT32 *) (pc + 4)); + + if (buffer != GLX_FRONT_LEFT_EXT) + return __glXError(GLXBadPixmap); + + context = __glXForceCurrent (cl, req->contextTag, &error); + if (!context) + return error; + + if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, + DixReadAccess, &pGlxDraw, &error)) + return error; + + if (!context->textureFromPixmap) + return __glXError(GLXUnsupportedPrivateRequest); + + return context->textureFromPixmap->bindTexImage(context, + buffer, + pGlxDraw); +} + +int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + ClientPtr client = cl->client; + __GLXdrawable *pGlxDraw; + __GLXcontext *context; + GLXDrawable drawId; + int buffer; + int error; + + REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); + + pc += __GLX_VENDPRIV_HDR_SIZE; + + drawId = *((CARD32 *) (pc)); + buffer = *((INT32 *) (pc + 4)); + + context = __glXForceCurrent (cl, req->contextTag, &error); + if (!context) + return error; + + if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, + DixReadAccess, &pGlxDraw, &error)) + return error; + + if (!context->textureFromPixmap) + return __glXError(GLXUnsupportedPrivateRequest); + + return context->textureFromPixmap->releaseTexImage(context, + buffer, + pGlxDraw); +} + +int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXContextTag tag = req->contextTag; + __GLXcontext *glxc = NULL; + __GLXdrawable *pGlxDraw; + ClientPtr client = cl->client; + GLXDrawable drawId; + int error; + int x, y, width, height; + + (void) client; + (void) req; + + REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20); + + pc += __GLX_VENDPRIV_HDR_SIZE; + + drawId = *((CARD32 *) (pc)); + x = *((INT32 *) (pc + 4)); + y = *((INT32 *) (pc + 8)); + width = *((INT32 *) (pc + 12)); + height = *((INT32 *) (pc + 16)); + + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXError(GLXBadContextTag); + } + /* + ** The calling thread is swapping its current drawable. In this case, + ** glxSwapBuffers is in both GL and X streams, in terms of + ** sequentiality. + */ + if (__glXForceCurrent(cl, tag, &error)) { + /* + ** Do whatever is needed to make sure that all preceding requests + ** in both streams are completed before the swap is executed. + */ + CALL_Finish( GET_DISPATCH(), () ); + __GLX_NOTE_FLUSHED_CMDS(glxc); + } else { + return error; + } + } + + pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); + if (!pGlxDraw) + return error; + + if (pGlxDraw == NULL || + pGlxDraw->type != GLX_DRAWABLE_WINDOW || + pGlxDraw->copySubBuffer == NULL) + return __glXError(GLXBadDrawable); + + (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height); + + return Success; +} + +/* +** Get drawable attributes +*/ +static int +DoGetDrawableAttributes(__GLXclientState *cl, XID drawId) +{ + ClientPtr client = cl->client; + xGLXGetDrawableAttributesReply reply; + __GLXdrawable *pGlxDraw; + CARD32 attributes[6]; + int numAttribs, error; + + if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, + DixGetAttrAccess, &pGlxDraw, &error)) + return error; + + numAttribs = 3; + reply.length = numAttribs << 1; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.numAttribs = numAttribs; + + attributes[0] = GLX_TEXTURE_TARGET_EXT; + attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT : + GLX_TEXTURE_RECTANGLE_EXT; + attributes[2] = GLX_Y_INVERTED_EXT; + attributes[3] = GL_FALSE; + attributes[4] = GLX_EVENT_MASK; + attributes[5] = pGlxDraw->eventMask; + + if (client->swapped) { + __glXSwapGetDrawableAttributesReply(client, &reply, attributes); + } else { + WriteToClient(client, sz_xGLXGetDrawableAttributesReply, + (char *)&reply); + WriteToClient(client, reply.length * sizeof (CARD32), + (char *)attributes); + } + + return Success; +} + +int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; + + REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesReq); + + return DoGetDrawableAttributes(cl, req->drawable); +} + +int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetDrawableAttributesSGIXReq *req = + (xGLXGetDrawableAttributesSGIXReq *)pc; + + REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq); + + return DoGetDrawableAttributes(cl, req->drawable); +} + +/************************************************************************/ + +/* +** Render and Renderlarge are not in the GLX API. They are used by the GLX +** client library to send batches of GL rendering commands. +*/ + +/* +** Execute all the drawing commands in a request. +*/ +int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc) +{ + xGLXRenderReq *req; + ClientPtr client= cl->client; + int left, cmdlen, error; + int commandsDone; + CARD16 opcode; + __GLXrenderHeader *hdr; + __GLXcontext *glxc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_AT_LEAST_SIZE(xGLXRenderReq); + + req = (xGLXRenderReq *) pc; + if (client->swapped) { + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + } + + glxc = __glXForceCurrent(cl, req->contextTag, &error); + if (!glxc) { + return error; + } + + commandsDone = 0; + pc += sz_xGLXRenderReq; + left = (req->length << 2) - sz_xGLXRenderReq; + while (left > 0) { + __GLXrenderSizeData entry; + int extra; + __GLXdispatchRenderProcPtr proc; + int err; + + if (left < sizeof(__GLXrenderHeader)) + return BadLength; + + /* + ** Verify that the header length and the overall length agree. + ** Also, each command must be word aligned. + */ + hdr = (__GLXrenderHeader *) pc; + if (client->swapped) { + __GLX_SWAP_SHORT(&hdr->length); + __GLX_SWAP_SHORT(&hdr->opcode); + } + cmdlen = hdr->length; + opcode = hdr->opcode; + + /* + ** Check for core opcodes and grab entry data. + */ + err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry); + proc = (__GLXdispatchRenderProcPtr) + __glXGetProtocolDecodeFunction(& Render_dispatch_info, + opcode, client->swapped); + + if ((err < 0) || (proc == NULL)) { + client->errorValue = commandsDone; + return __glXError(GLXBadRenderRequest); + } + + if (entry.varsize) { + /* variable size command */ + extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE, + client->swapped); + if (extra < 0) { + extra = 0; + } + if (cmdlen != __GLX_PAD(entry.bytes + extra)) { + return BadLength; + } + } else { + /* constant size command */ + if (cmdlen != __GLX_PAD(entry.bytes)) { + return BadLength; + } + } + if (left < cmdlen) { + return BadLength; + } + + /* + ** Skip over the header and execute the command. We allow the + ** caller to trash the command memory. This is useful especially + ** for things that require double alignment - they can just shift + ** the data towards lower memory (trashing the header) by 4 bytes + ** and achieve the required alignment. + */ + (*proc)(pc + __GLX_RENDER_HDR_SIZE); + pc += cmdlen; + left -= cmdlen; + commandsDone++; + } + __GLX_NOTE_UNFLUSHED_CMDS(glxc); + return Success; +} + + +/* +** Execute a large rendering request (one that spans multiple X requests). +*/ +int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc) +{ + xGLXRenderLargeReq *req; + ClientPtr client= cl->client; + size_t dataBytes; + __GLXrenderLargeHeader *hdr; + __GLXcontext *glxc; + int error; + CARD16 opcode; + __GLX_DECLARE_SWAP_VARIABLES; + + req = (xGLXRenderLargeReq *) pc; + if (client->swapped) { + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(&req->dataBytes); + __GLX_SWAP_SHORT(&req->requestNumber); + __GLX_SWAP_SHORT(&req->requestTotal); + } + + glxc = __glXForceCurrent(cl, req->contextTag, &error); + if (!glxc) { + /* Reset in case this isn't 1st request. */ + __glXResetLargeCommandStatus(cl); + return error; + } + dataBytes = req->dataBytes; + + /* + ** Check the request length. + */ + if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) { + client->errorValue = req->length; + /* Reset in case this isn't 1st request. */ + __glXResetLargeCommandStatus(cl); + return BadLength; + } + pc += sz_xGLXRenderLargeReq; + + if (cl->largeCmdRequestsSoFar == 0) { + __GLXrenderSizeData entry; + int extra; + size_t cmdlen; + int err; + + /* + ** This is the first request of a multi request command. + ** Make enough space in the buffer, then copy the entire request. + */ + if (req->requestNumber != 1) { + client->errorValue = req->requestNumber; + return __glXError(GLXBadLargeRequest); + } + + hdr = (__GLXrenderLargeHeader *) pc; + if (client->swapped) { + __GLX_SWAP_INT(&hdr->length); + __GLX_SWAP_INT(&hdr->opcode); + } + cmdlen = hdr->length; + opcode = hdr->opcode; + + /* + ** Check for core opcodes and grab entry data. + */ + err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry); + if (err < 0) { + client->errorValue = opcode; + return __glXError(GLXBadLargeRequest); + } + + if (entry.varsize) { + /* + ** If it's a variable-size command (a command whose length must + ** be computed from its parameters), all the parameters needed + ** will be in the 1st request, so it's okay to do this. + */ + extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE, + client->swapped); + if (extra < 0) { + extra = 0; + } + /* large command's header is 4 bytes longer, so add 4 */ + if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) { + return BadLength; + } + } else { + /* constant size command */ + if (cmdlen != __GLX_PAD(entry.bytes + 4)) { + return BadLength; + } + } + /* + ** Make enough space in the buffer, then copy the entire request. + */ + if (cl->largeCmdBufSize < cmdlen) { + if (!cl->largeCmdBuf) { + cl->largeCmdBuf = (GLbyte *) malloc(cmdlen); + } else { + cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, cmdlen); + } + if (!cl->largeCmdBuf) { + return BadAlloc; + } + cl->largeCmdBufSize = cmdlen; + } + memcpy(cl->largeCmdBuf, pc, dataBytes); + + cl->largeCmdBytesSoFar = dataBytes; + cl->largeCmdBytesTotal = cmdlen; + cl->largeCmdRequestsSoFar = 1; + cl->largeCmdRequestsTotal = req->requestTotal; + return Success; + + } else { + /* + ** We are receiving subsequent (i.e. not the first) requests of a + ** multi request command. + */ + + /* + ** Check the request number and the total request count. + */ + if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) { + client->errorValue = req->requestNumber; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); + } + if (req->requestTotal != cl->largeCmdRequestsTotal) { + client->errorValue = req->requestTotal; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); + } + + /* + ** Check that we didn't get too much data. + */ + if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) { + client->errorValue = dataBytes; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); + } + memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes); + cl->largeCmdBytesSoFar += dataBytes; + cl->largeCmdRequestsSoFar++; + + if (req->requestNumber == cl->largeCmdRequestsTotal) { + __GLXdispatchRenderProcPtr proc; + + /* + ** This is the last request; it must have enough bytes to complete + ** the command. + */ + /* NOTE: the two pad macros have been added below; they are needed + ** because the client library pads the total byte count, but not + ** the per-request byte counts. The Protocol Encoding says the + ** total byte count should not be padded, so a proposal will be + ** made to the ARB to relax the padding constraint on the total + ** byte count, thus preserving backward compatibility. Meanwhile, + ** the padding done below fixes a bug that did not allow + ** large commands of odd sizes to be accepted by the server. + */ + if (__GLX_PAD(cl->largeCmdBytesSoFar) != + __GLX_PAD(cl->largeCmdBytesTotal)) { + client->errorValue = dataBytes; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); + } + hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf; + /* + ** The opcode and length field in the header had already been + ** swapped when the first request was received. + ** + ** Use the opcode to index into the procedure table. + */ + opcode = hdr->opcode; + + proc = (__GLXdispatchRenderProcPtr) + __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode, + client->swapped); + if (proc == NULL) { + client->errorValue = opcode; + return __glXError(GLXBadLargeRequest); + } + + /* + ** Skip over the header and execute the command. + */ + (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE); + __GLX_NOTE_UNFLUSHED_CMDS(glxc); + + /* + ** Reset for the next RenderLarge series. + */ + __glXResetLargeCommandStatus(cl); + } else { + /* + ** This is neither the first nor the last request. + */ + } + return Success; + } +} + +/************************************************************************/ + +/* +** No support is provided for the vendor-private requests other than +** allocating the entry points in the dispatch table. +*/ + +int __glXDisp_VendorPrivate(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLint vendorcode = req->vendorCode; + __GLXdispatchVendorPrivProcPtr proc; + + REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); + + proc = (__GLXdispatchVendorPrivProcPtr) + __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, + vendorcode, 0); + if (proc != NULL) { + (*proc)(cl, (GLbyte*)req); + return Success; + } + + cl->client->errorValue = req->vendorCode; + return __glXError(GLXUnsupportedPrivateRequest); +} + +int __glXDisp_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLint vendorcode = req->vendorCode; + __GLXdispatchVendorPrivProcPtr proc; + + REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); + + proc = (__GLXdispatchVendorPrivProcPtr) + __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, + vendorcode, 0); + if (proc != NULL) { + return (*proc)(cl, (GLbyte*)req); + } + + cl->client->errorValue = vendorcode; + return __glXError(GLXUnsupportedPrivateRequest); +} + +int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; + xGLXQueryExtensionsStringReply reply; + __GLXscreen *pGlxScreen; + size_t n, length; + char *buf; + int err; + + REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq); + + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; + + n = strlen(pGlxScreen->GLXextensions) + 1; + length = __GLX_PAD(n) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = length; + reply.n = n; + + /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/ + buf = (char *) malloc(length << 2); + if (buf == NULL) + return BadAlloc; + memcpy(buf, pGlxScreen->GLXextensions, n); + + if (client->swapped) { + glxSwapQueryExtensionsStringReply(client, &reply, buf); + } else { + WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); + WriteToClient(client, (int)(length << 2), (char *)buf); + } + + free(buf); + return Success; +} + +int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; + xGLXQueryServerStringReply reply; + size_t n, length; + const char *ptr; + char *buf; + __GLXscreen *pGlxScreen; + int err; + char ver_str[16]; + + REQUEST_SIZE_MATCH(xGLXQueryServerStringReq); + + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; + + switch(req->name) { + case GLX_VENDOR: + ptr = pGlxScreen->GLXvendor; + break; + case GLX_VERSION: + /* Return to the server version rather than the screen version + * to prevent confusion when they do not match. + */ + snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion); + ptr = ver_str; + break; + case GLX_EXTENSIONS: + ptr = pGlxScreen->GLXextensions; + break; + default: + return BadValue; + } + + n = strlen(ptr) + 1; + length = __GLX_PAD(n) >> 2; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = length; + reply.n = n; + + buf = (char *) malloc(length << 2); + if (buf == NULL) { + return BadAlloc; + } + memcpy(buf, ptr, n); + + if (client->swapped) { + glxSwapQueryServerStringReply(client, &reply, buf); + } else { + WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); + WriteToClient(client, (int)(length << 2), buf); + } + + free(buf); + return Success; +} + +int __glXDisp_ClientInfo(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; + const char *buf; + + REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); + + buf = (const char *)(req+1); + if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq))) + return BadLength; + + cl->GLClientmajorVersion = req->major; + cl->GLClientminorVersion = req->minor; + free(cl->GLClientextensions); + cl->GLClientextensions = strdup(buf); + + return Success; +} diff --git a/xorg-server/glx/glxcmdsswap.c b/xorg-server/glx/glxcmdsswap.c index a6633741f..3bb4cade9 100644 --- a/xorg-server/glx/glxcmdsswap.c +++ b/xorg-server/glx/glxcmdsswap.c @@ -1,770 +1,915 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-#include "glxserver.h"
-#include "glxutil.h"
-#include <GL/glxtokens.h>
-#include <unpack.h>
-#include <pixmapstr.h>
-#include <windowstr.h>
-#include "glxext.h"
-#include "glapitable.h"
-#include "glapi.h"
-#include "glthread.h"
-#include "dispatch.h"
-#include "indirect_dispatch.h"
-#include "indirect_table.h"
-#include "indirect_util.h"
-
-
-/************************************************************************/
-
-/*
-** Byteswapping versions of GLX commands. In most cases they just swap
-** the incoming arguments and then call the unswapped routine. For commands
-** that have replies, a separate swapping routine for the reply is provided;
-** it is called at the end of the unswapped routine.
-*/
-
-int __glXDispSwap_CreateContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->visual);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->shareList);
-
- return __glXDisp_CreateContext(cl, pc);
-}
-
-int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->renderType);
- __GLX_SWAP_INT(&req->shareList);
-
- return __glXDisp_CreateNewContext(cl, pc);
-}
-
-int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextWithConfigSGIXReq *req =
- (xGLXCreateContextWithConfigSGIXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->renderType);
- __GLX_SWAP_INT(&req->shareList);
-
- return __glXDisp_CreateContextWithConfigSGIX(cl, pc);
-}
-
-int __glXDispSwap_DestroyContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
-
- return __glXDisp_DestroyContext(cl, pc);
-}
-
-int __glXDispSwap_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->oldContextTag);
-
- return __glXDisp_MakeCurrent(cl, pc);
-}
-
-int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->readdrawable);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->oldContextTag);
-
- return __glXDisp_MakeContextCurrent(cl, pc);
-}
-
-int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->readable);
- __GLX_SWAP_INT(&req->context);
- __GLX_SWAP_INT(&req->oldContextTag);
-
- return __glXDisp_MakeCurrentReadSGI(cl, pc);
-}
-
-int __glXDispSwap_IsDirect(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
-
- return __glXDisp_IsDirect(cl, pc);
-}
-
-int __glXDispSwap_QueryVersion(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->majorVersion);
- __GLX_SWAP_INT(&req->minorVersion);
-
- return __glXDisp_QueryVersion(cl, pc);
-}
-
-int __glXDispSwap_WaitGL(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- return __glXDisp_WaitGL(cl, pc);
-}
-
-int __glXDispSwap_WaitX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- return __glXDisp_WaitX(cl, pc);
-}
-
-int __glXDispSwap_CopyContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->source);
- __GLX_SWAP_INT(&req->dest);
- __GLX_SWAP_INT(&req->mask);
-
- return __glXDisp_CopyContext(cl, pc);
-}
-
-int __glXDispSwap_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->screen);
- return __glXDisp_GetVisualConfigs(cl, pc);
-}
-
-int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->screen);
- return __glXDisp_GetFBConfigs(cl, pc);
-}
-
-int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->screen);
- return __glXDisp_GetFBConfigsSGIX(cl, pc);
-}
-
-int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->visual);
- __GLX_SWAP_INT(&req->pixmap);
- __GLX_SWAP_INT(&req->glxpixmap);
-
- return __glXDisp_CreateGLXPixmap(cl, pc);
-}
-
-int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
- CARD32 *attribs;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->pixmap);
- __GLX_SWAP_INT(&req->glxpixmap);
- __GLX_SWAP_INT(&req->numAttribs);
- attribs = (CARD32*)(req + 1);
- __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
-
- return __glXDisp_CreatePixmap(cl, pc);
-}
-
-int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPixmapWithConfigSGIXReq *req =
- (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->pixmap);
- __GLX_SWAP_INT(&req->glxpixmap);
-
- return __glXDisp_CreateGLXPixmapWithConfigSGIX(cl, pc);
-}
-
-int __glXDispSwap_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->glxpixmap);
-
- return __glXDisp_DestroyGLXPixmap(cl, pc);
-}
-
-int __glXDispSwap_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->glxpixmap);
-
- return __glXDisp_DestroyGLXPixmap(cl, pc);
-}
-
-int __glXDispSwap_QueryContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->context);
-
- return __glXDisp_QueryContext(cl, pc);
-}
-
-int __glXDispSwap_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- CARD32 *attribs;
-
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->pbuffer);
- __GLX_SWAP_INT(&req->numAttribs);
- attribs = (CARD32*)(req + 1);
- __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
-
- return __glXDisp_CreatePbuffer(cl, pc);
-}
-
-int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->pbuffer);
- __GLX_SWAP_INT(&req->width);
- __GLX_SWAP_INT(&req->height);
-
- return __glXDisp_CreateGLXPbufferSGIX(cl, pc);
-}
-
-int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->pbuffer);
-
- return __glXDisp_DestroyPbuffer(cl, pc);
-}
-
-int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->pbuffer);
-
- return __glXDisp_DestroyGLXPbufferSGIX(cl, pc);
-}
-
-int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXChangeDrawableAttributesReq *req =
- (xGLXChangeDrawableAttributesReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- CARD32 *attribs;
-
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->numAttribs);
- attribs = (CARD32*)(req + 1);
- __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
-
- return __glXDisp_ChangeDrawableAttributes(cl, pc);
-}
-
-int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl,
- GLbyte *pc)
-{
- xGLXChangeDrawableAttributesSGIXReq *req =
- (xGLXChangeDrawableAttributesSGIXReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- CARD32 *attribs;
-
- __GLX_SWAP_INT(&req->drawable);
- __GLX_SWAP_INT(&req->numAttribs);
- attribs = (CARD32*)(req + 1);
- __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
-
- return __glXDisp_ChangeDrawableAttributesSGIX(cl, pc);
-}
-
-int __glXDispSwap_CreateWindow(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- CARD32 *attribs;
-
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->fbconfig);
- __GLX_SWAP_INT(&req->window);
- __GLX_SWAP_INT(&req->glxwindow);
- __GLX_SWAP_INT(&req->numAttribs);
- attribs = (CARD32*)(req + 1);
- __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
-
- return __glXDisp_CreateWindow(cl, pc);
-}
-
-int __glXDispSwap_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_INT(&req->glxwindow);
-
- return __glXDisp_DestroyWindow(cl, pc);
-}
-
-int __glXDispSwap_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(&req->drawable);
-
- return __glXDisp_SwapBuffers(cl, pc);
-}
-
-int __glXDispSwap_UseXFont(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(&req->font);
- __GLX_SWAP_INT(&req->first);
- __GLX_SWAP_INT(&req->count);
- __GLX_SWAP_INT(&req->listBase);
-
- return __glXDisp_UseXFont(cl, pc);
-}
-
-
-int __glXDispSwap_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
-
- return __glXDisp_QueryExtensionsString(cl, pc);
-}
-
-int __glXDispSwap_QueryServerString(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->screen);
- __GLX_SWAP_INT(&req->name);
-
- return __glXDisp_QueryServerString(cl, pc);
-}
-
-int __glXDispSwap_ClientInfo(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->major);
- __GLX_SWAP_INT(&req->minor);
- __GLX_SWAP_INT(&req->numbytes);
-
- return __glXDisp_ClientInfo(cl, pc);
-}
-
-int __glXDispSwap_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->context);
-
- return __glXDisp_QueryContextInfoEXT(cl, pc);
-}
-
-int __glXDispSwap_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- GLXDrawable *drawId;
- int *buffer;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- pc += __GLX_VENDPRIV_HDR_SIZE;
-
- drawId = ((GLXDrawable *) (pc));
- buffer = ((int *) (pc + 4));
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(drawId);
- __GLX_SWAP_INT(buffer);
-
- return __glXDisp_BindTexImageEXT(cl, (GLbyte *)pc);
-}
-
-int __glXDispSwap_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- GLXDrawable *drawId;
- int *buffer;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- pc += __GLX_VENDPRIV_HDR_SIZE;
-
- drawId = ((GLXDrawable *) (pc));
- buffer = ((int *) (pc + 4));
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(drawId);
- __GLX_SWAP_INT(buffer);
-
- return __glXDisp_ReleaseTexImageEXT(cl, (GLbyte *)pc);
-}
-
-int __glXDispSwap_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
- GLXDrawable *drawId;
- int *buffer;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- (void) drawId;
- (void) buffer;
-
- pc += __GLX_VENDPRIV_HDR_SIZE;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(pc);
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + 8);
- __GLX_SWAP_INT(pc + 12);
- __GLX_SWAP_INT(pc + 16);
-
- return __glXDisp_CopySubBufferMESA(cl, pc);
-
-}
-
-int __glXDispSwap_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *)pc;
- CARD32 *data;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- data = (CARD32 *) (req + 1);
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
- __GLX_SWAP_INT(data);
-
- return __glXDisp_GetDrawableAttributesSGIX(cl, pc);
-}
-
-int __glXDispSwap_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->drawable);
-
- return __glXDisp_GetDrawableAttributes(cl, pc);
-}
-
-
-/************************************************************************/
-
-/*
-** Swap replies.
-*/
-
-void __glXSwapMakeCurrentReply(ClientPtr client, xGLXMakeCurrentReply *reply)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->contextTag);
- WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)reply);
-}
-
-void __glXSwapIsDirectReply(ClientPtr client, xGLXIsDirectReply *reply)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- WriteToClient(client, sz_xGLXIsDirectReply, (char *)reply);
-}
-
-void __glXSwapQueryVersionReply(ClientPtr client, xGLXQueryVersionReply *reply)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->majorVersion);
- __GLX_SWAP_INT(&reply->minorVersion);
- WriteToClient(client, sz_xGLXQueryVersionReply, (char *)reply);
-}
-
-void glxSwapQueryExtensionsStringReply(ClientPtr client,
- xGLXQueryExtensionsStringReply *reply, char *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->n);
- WriteToClient(client, sz_xGLXQueryExtensionsStringReply, (char *)reply);
- __GLX_SWAP_INT_ARRAY((int *)buf, length);
- WriteToClient(client, length << 2, buf);
-}
-
-void glxSwapQueryServerStringReply(ClientPtr client,
- xGLXQueryServerStringReply *reply, char *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->n);
- WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)reply);
- /** no swap is needed for an array of chars **/
- /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */
- WriteToClient(client, length << 2, buf);
-}
-
-void __glXSwapQueryContextInfoEXTReply(ClientPtr client, xGLXQueryContextInfoEXTReply *reply, int *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->n);
- WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)reply);
- __GLX_SWAP_INT_ARRAY((int *)buf, length);
- WriteToClient(client, length << 2, (char *)buf);
-}
-
-void __glXSwapGetDrawableAttributesReply(ClientPtr client,
- xGLXGetDrawableAttributesReply *reply, CARD32 *buf)
-{
- int length = reply->length;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->numAttribs);
- WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)reply);
- __GLX_SWAP_INT_ARRAY((int *)buf, length);
- WriteToClient(client, length << 2, (char *)buf);
-}
-
-/************************************************************************/
-
-/*
-** Render and Renderlarge are not in the GLX API. They are used by the GLX
-** client library to send batches of GL rendering commands.
-*/
-
-int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc)
-{
- return __glXDisp_Render(cl, pc);
-}
-
-/*
-** Execute a large rendering request (one that spans multiple X requests).
-*/
-int __glXDispSwap_RenderLarge(__GLXclientState *cl, GLbyte *pc)
-{
- return __glXDisp_RenderLarge(cl, pc);
-}
-
-/************************************************************************/
-
-/*
-** No support is provided for the vendor-private requests other than
-** allocating these entry points in the dispatch table.
-*/
-
-int __glXDispSwap_VendorPrivate(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req;
- GLint vendorcode;
- __GLXdispatchVendorPrivProcPtr proc;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- req = (xGLXVendorPrivateReq *) pc;
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
-
- vendorcode = req->vendorCode;
-
- proc = (__GLXdispatchVendorPrivProcPtr)
- __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
- vendorcode, 1);
- if (proc != NULL) {
- (*proc)(cl, (GLbyte*)req);
- return Success;
- }
-
- cl->client->errorValue = req->vendorCode;
- return __glXError(GLXUnsupportedPrivateRequest);
-}
-
-
-int __glXDispSwap_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateWithReplyReq *req;
- GLint vendorcode;
- __GLXdispatchVendorPrivProcPtr proc;
-
- __GLX_DECLARE_SWAP_VARIABLES;
-
- req = (xGLXVendorPrivateWithReplyReq *) pc;
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
-
- vendorcode = req->vendorCode;
-
- proc = (__GLXdispatchVendorPrivProcPtr)
- __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
- vendorcode, 1);
- if (proc != NULL) {
- return (*proc)(cl, (GLbyte*)req);
- }
-
- cl->client->errorValue = req->vendorCode;
- return __glXError(GLXUnsupportedPrivateRequest);
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> +#include "glxserver.h" +#include "glxutil.h" +#include <GL/glxtokens.h> +#include <unpack.h> +#include <pixmapstr.h> +#include <windowstr.h> +#include "glxext.h" +#include "glapitable.h" +#include "glapi.h" +#include "glthread.h" +#include "dispatch.h" +#include "indirect_dispatch.h" +#include "indirect_table.h" +#include "indirect_util.h" + + +/************************************************************************/ + +/* +** Byteswapping versions of GLX commands. In most cases they just swap +** the incoming arguments and then call the unswapped routine. For commands +** that have replies, a separate swapping routine for the reply is provided; +** it is called at the end of the unswapped routine. +*/ + +int __glXDispSwap_CreateContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXCreateContextReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->visual); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->shareList); + + return __glXDisp_CreateContext(cl, pc); +} + +int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXCreateNewContextReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->renderType); + __GLX_SWAP_INT(&req->shareList); + + return __glXDisp_CreateNewContext(cl, pc); +} + +int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateContextWithConfigSGIXReq *req = + (xGLXCreateContextWithConfigSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->renderType); + __GLX_SWAP_INT(&req->shareList); + + return __glXDisp_CreateContextWithConfigSGIX(cl, pc); +} + +int __glXDispSwap_DestroyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXDestroyContextReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + + return __glXDisp_DestroyContext(cl, pc); +} + +int __glXDispSwap_MakeCurrent(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXMakeCurrentReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->oldContextTag); + + return __glXDisp_MakeCurrent(cl, pc); +} + +int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->readdrawable); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->oldContextTag); + + return __glXDisp_MakeContextCurrent(cl, pc); +} + +int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->readable); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->oldContextTag); + + return __glXDisp_MakeCurrentReadSGI(cl, pc); +} + +int __glXDispSwap_IsDirect(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXIsDirectReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + + return __glXDisp_IsDirect(cl, pc); +} + +int __glXDispSwap_QueryVersion(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXQueryVersionReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->majorVersion); + __GLX_SWAP_INT(&req->minorVersion); + + return __glXDisp_QueryVersion(cl, pc); +} + +int __glXDispSwap_WaitGL(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXWaitGLReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + return __glXDisp_WaitGL(cl, pc); +} + +int __glXDispSwap_WaitX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXWaitXReq *req = (xGLXWaitXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXWaitXReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + + return __glXDisp_WaitX(cl, pc); +} + +int __glXDispSwap_CopyContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXCopyContextReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->source); + __GLX_SWAP_INT(&req->dest); + __GLX_SWAP_INT(&req->mask); + + return __glXDisp_CopyContext(cl, pc); +} + +int __glXDispSwap_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq); + + __GLX_SWAP_INT(&req->screen); + return __glXDisp_GetVisualConfigs(cl, pc); +} + +int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq); + + __GLX_SWAP_INT(&req->screen); + return __glXDisp_GetFBConfigs(cl, pc); +} + +int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXGetFBConfigsSGIXReq); + + __GLX_SWAP_INT(&req->screen); + return __glXDisp_GetFBConfigsSGIX(cl, pc); +} + +int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->visual); + __GLX_SWAP_INT(&req->pixmap); + __GLX_SWAP_INT(&req->glxpixmap); + + return __glXDisp_CreateGLXPixmap(cl, pc); +} + +int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + CARD32 *attribs; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pixmap); + __GLX_SWAP_INT(&req->glxpixmap); + __GLX_SWAP_INT(&req->numAttribs); + + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3); + attribs = (CARD32*)(req + 1); + __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); + + return __glXDisp_CreatePixmap(cl, pc); +} + +int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPixmapWithConfigSGIXReq *req = + (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pixmap); + __GLX_SWAP_INT(&req->glxpixmap); + + return __glXDisp_CreateGLXPixmapWithConfigSGIX(cl, pc); +} + +int __glXDispSwap_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->glxpixmap); + + return __glXDisp_DestroyGLXPixmap(cl, pc); +} + +int __glXDispSwap_DestroyPixmap(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->glxpixmap); + + return __glXDisp_DestroyGLXPixmap(cl, pc); +} + +int __glXDispSwap_QueryContext(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXQueryContextReq); + + __GLX_SWAP_INT(&req->context); + + return __glXDisp_QueryContext(cl, pc); +} + +int __glXDispSwap_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + CARD32 *attribs; + + REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq); + + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pbuffer); + __GLX_SWAP_INT(&req->numAttribs); + + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3); + attribs = (CARD32*)(req + 1); + __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); + + return __glXDisp_CreatePbuffer(cl, pc); +} + +int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXCreateGLXPbufferSGIXReq); + + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pbuffer); + __GLX_SWAP_INT(&req->width); + __GLX_SWAP_INT(&req->height); + + return __glXDisp_CreateGLXPbufferSGIX(cl, pc); +} + +int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq); + + __GLX_SWAP_INT(&req->pbuffer); + + return __glXDisp_DestroyPbuffer(cl, pc); +} + +int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq); + + __GLX_SWAP_INT(&req->pbuffer); + + return __glXDisp_DestroyGLXPbufferSGIX(cl, pc); +} + +int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXChangeDrawableAttributesReq *req = + (xGLXChangeDrawableAttributesReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + CARD32 *attribs; + + REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq); + + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->numAttribs); + + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3); + attribs = (CARD32*)(req + 1); + __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); + + return __glXDisp_ChangeDrawableAttributes(cl, pc); +} + +int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl, + GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXChangeDrawableAttributesSGIXReq *req = + (xGLXChangeDrawableAttributesSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + CARD32 *attribs; + + REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq); + + __GLX_SWAP_INT(&req->drawable); + __GLX_SWAP_INT(&req->numAttribs); + + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3); + attribs = (CARD32*)(req + 1); + __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); + + return __glXDisp_ChangeDrawableAttributesSGIX(cl, pc); +} + +int __glXDispSwap_CreateWindow(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + CARD32 *attribs; + + REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq); + + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->window); + __GLX_SWAP_INT(&req->glxwindow); + __GLX_SWAP_INT(&req->numAttribs); + + if (req->numAttribs > (UINT32_MAX >> 3)) { + client->errorValue = req->numAttribs; + return BadValue; + } + REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3); + attribs = (CARD32*)(req + 1); + __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); + + return __glXDisp_CreateWindow(cl, pc); +} + +int __glXDispSwap_DestroyWindow(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXDestroyWindowReq); + + __GLX_SWAP_INT(&req->glxwindow); + + return __glXDisp_DestroyWindow(cl, pc); +} + +int __glXDispSwap_SwapBuffers(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXSwapBuffersReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(&req->drawable); + + return __glXDisp_SwapBuffers(cl, pc); +} + +int __glXDispSwap_UseXFont(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXUseXFontReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(&req->font); + __GLX_SWAP_INT(&req->first); + __GLX_SWAP_INT(&req->count); + __GLX_SWAP_INT(&req->listBase); + + return __glXDisp_UseXFont(cl, pc); +} + + +int __glXDispSwap_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + + return __glXDisp_QueryExtensionsString(cl, pc); +} + +int __glXDispSwap_QueryServerString(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXQueryServerStringReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->name); + + return __glXDisp_QueryServerString(cl, pc); +} + +int __glXDispSwap_ClientInfo(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->major); + __GLX_SWAP_INT(&req->minor); + __GLX_SWAP_INT(&req->numbytes); + + return __glXDisp_ClientInfo(cl, pc); +} + +int __glXDispSwap_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + + return __glXDisp_QueryContextInfoEXT(cl, pc); +} + +int __glXDispSwap_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXDrawable *drawId; + int *buffer; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); + + pc += __GLX_VENDPRIV_HDR_SIZE; + + drawId = ((GLXDrawable *) (pc)); + buffer = ((int *) (pc + 4)); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(drawId); + __GLX_SWAP_INT(buffer); + + return __glXDisp_BindTexImageEXT(cl, (GLbyte *)pc); +} + +int __glXDispSwap_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXDrawable *drawId; + int *buffer; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); + + pc += __GLX_VENDPRIV_HDR_SIZE; + + drawId = ((GLXDrawable *) (pc)); + buffer = ((int *) (pc + 4)); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(drawId); + __GLX_SWAP_INT(buffer); + + return __glXDisp_ReleaseTexImageEXT(cl, (GLbyte *)pc); +} + +int __glXDispSwap_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXDrawable *drawId; + int *buffer; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20); + + (void) drawId; + (void) buffer; + + pc += __GLX_VENDPRIV_HDR_SIZE; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(pc); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + + return __glXDisp_CopySubBufferMESA(cl, pc); + +} + +int __glXDispSwap_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *)pc; + CARD32 *data; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq); + + data = (CARD32 *) (req + 1); + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(data); + + return __glXDisp_GetDrawableAttributesSGIX(cl, pc); +} + +int __glXDispSwap_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; + __GLX_DECLARE_SWAP_VARIABLES; + + REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesReq); + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->drawable); + + return __glXDisp_GetDrawableAttributes(cl, pc); +} + + +/************************************************************************/ + +/* +** Swap replies. +*/ + +void __glXSwapMakeCurrentReply(ClientPtr client, xGLXMakeCurrentReply *reply) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->contextTag); + WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)reply); +} + +void __glXSwapIsDirectReply(ClientPtr client, xGLXIsDirectReply *reply) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + WriteToClient(client, sz_xGLXIsDirectReply, (char *)reply); +} + +void __glXSwapQueryVersionReply(ClientPtr client, xGLXQueryVersionReply *reply) +{ + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->majorVersion); + __GLX_SWAP_INT(&reply->minorVersion); + WriteToClient(client, sz_xGLXQueryVersionReply, (char *)reply); +} + +void glxSwapQueryExtensionsStringReply(ClientPtr client, + xGLXQueryExtensionsStringReply *reply, char *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->n); + WriteToClient(client, sz_xGLXQueryExtensionsStringReply, (char *)reply); + __GLX_SWAP_INT_ARRAY((int *)buf, length); + WriteToClient(client, length << 2, buf); +} + +void glxSwapQueryServerStringReply(ClientPtr client, + xGLXQueryServerStringReply *reply, char *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->n); + WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)reply); + /** no swap is needed for an array of chars **/ + /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */ + WriteToClient(client, length << 2, buf); +} + +void __glXSwapQueryContextInfoEXTReply(ClientPtr client, xGLXQueryContextInfoEXTReply *reply, int *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->n); + WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)reply); + __GLX_SWAP_INT_ARRAY((int *)buf, length); + WriteToClient(client, length << 2, (char *)buf); +} + +void __glXSwapGetDrawableAttributesReply(ClientPtr client, + xGLXGetDrawableAttributesReply *reply, CARD32 *buf) +{ + int length = reply->length; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + __GLX_SWAP_SHORT(&reply->sequenceNumber); + __GLX_SWAP_INT(&reply->length); + __GLX_SWAP_INT(&reply->numAttribs); + WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)reply); + __GLX_SWAP_INT_ARRAY((int *)buf, length); + WriteToClient(client, length << 2, (char *)buf); +} + +/************************************************************************/ + +/* +** Render and Renderlarge are not in the GLX API. They are used by the GLX +** client library to send batches of GL rendering commands. +*/ + +int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc) +{ + return __glXDisp_Render(cl, pc); +} + +/* +** Execute a large rendering request (one that spans multiple X requests). +*/ +int __glXDispSwap_RenderLarge(__GLXclientState *cl, GLbyte *pc) +{ + return __glXDisp_RenderLarge(cl, pc); +} + +/************************************************************************/ + +/* +** No support is provided for the vendor-private requests other than +** allocating these entry points in the dispatch table. +*/ + +int __glXDispSwap_VendorPrivate(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req; + GLint vendorcode; + __GLXdispatchVendorPrivProcPtr proc; + + __GLX_DECLARE_SWAP_VARIABLES; + + req = (xGLXVendorPrivateReq *) pc; + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + + vendorcode = req->vendorCode; + + proc = (__GLXdispatchVendorPrivProcPtr) + __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, + vendorcode, 1); + if (proc != NULL) { + (*proc)(cl, (GLbyte*)req); + return Success; + } + + cl->client->errorValue = req->vendorCode; + return __glXError(GLXUnsupportedPrivateRequest); +} + + +int __glXDispSwap_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateWithReplyReq *req; + GLint vendorcode; + __GLXdispatchVendorPrivProcPtr proc; + + __GLX_DECLARE_SWAP_VARIABLES; + + req = (xGLXVendorPrivateWithReplyReq *) pc; + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->vendorCode); + + vendorcode = req->vendorCode; + + proc = (__GLXdispatchVendorPrivProcPtr) + __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, + vendorcode, 1); + if (proc != NULL) { + return (*proc)(cl, (GLbyte*)req); + } + + cl->client->errorValue = req->vendorCode; + return __glXError(GLXUnsupportedPrivateRequest); +} diff --git a/xorg-server/glx/xfont.c b/xorg-server/glx/xfont.c index 9cd440a85..84a301f9b 100644 --- a/xorg-server/glx/xfont.c +++ b/xorg-server/glx/xfont.c @@ -1,184 +1,186 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "glxserver.h"
-#include "glxutil.h"
-#include "unpack.h"
-#include "glapitable.h"
-#include "glapi.h"
-#include "glthread.h"
-#include "dispatch.h"
-#include "indirect_dispatch.h"
-#include <GL/gl.h>
-#include <pixmapstr.h>
-#include <windowstr.h>
-#include <dixfontstr.h>
-
-/*
-** Make a single GL bitmap from a single X glyph
-*/
-static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci)
-{
- int i, j;
- int widthPadded; /* width of glyph in bytes, as padded by X */
- int allocBytes; /* bytes to allocate to store bitmap */
- int w; /* width of glyph in bits */
- int h; /* height of glyph */
- register unsigned char *pglyph;
- register unsigned char *p;
- unsigned char *allocbuf;
-#define __GL_CHAR_BUF_SIZE 2048
- unsigned char buf[__GL_CHAR_BUF_SIZE];
-
- w = GLYPHWIDTHPIXELS(pci);
- h = GLYPHHEIGHTPIXELS(pci);
- widthPadded = GLYPHWIDTHBYTESPADDED(pci);
-
- /*
- ** Use the local buf if possible, otherwise malloc.
- */
- allocBytes = widthPadded * h;
- if (allocBytes <= __GL_CHAR_BUF_SIZE) {
- p = buf;
- allocbuf = 0;
- } else {
- p = (unsigned char *) malloc(allocBytes);
- if (!p)
- return BadAlloc;
- allocbuf = p;
- }
-
- /*
- ** We have to reverse the picture, top to bottom
- */
-
- pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h-1)*widthPadded;
- for (j=0; j < h; j++) {
- for (i=0; i < widthPadded; i++) {
- p[i] = pglyph[i];
- }
- pglyph -= widthPadded;
- p += widthPadded;
- }
- CALL_Bitmap( GET_DISPATCH(), (w, h, -pci->metrics.leftSideBearing,
- pci->metrics.descent,
- pci->metrics.characterWidth, 0,
- allocbuf ? allocbuf : buf) );
-
- free(allocbuf);
- return Success;
-#undef __GL_CHAR_BUF_SIZE
-}
-
-/*
-** Create a GL bitmap for each character in the X font. The bitmap is stored
-** in a display list.
-*/
-
-static int
-MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base)
-{
- unsigned long i, nglyphs;
- CARD8 chs[2]; /* the font index we are going after */
- CharInfoPtr pci;
- int rv; /* return value */
- int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit;
-
- CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, FALSE) );
- CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst) );
- CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, 0) );
- CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
- CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
- CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, GLYPHPADBYTES) );
- for (i=0; i < count; i++) {
- chs[0] = (first + i) >> 8; /* high byte is first byte */
- chs[1] = first + i;
-
- (*pFont->get_glyphs)(pFont, 1, chs, (FontEncoding)encoding,
- &nglyphs, &pci);
-
- /*
- ** Define a display list containing just a glBitmap() call.
- */
- CALL_NewList( GET_DISPATCH(), (list_base + i, GL_COMPILE) );
- if (nglyphs ) {
- rv = __glXMakeBitmapFromGlyph(pFont, pci);
- if (rv) {
- return rv;
- }
- }
- CALL_EndList( GET_DISPATCH(), () );
- }
- return Success;
-}
-
-/************************************************************************/
-
-int __glXDisp_UseXFont(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXUseXFontReq *req;
- FontPtr pFont;
- GLuint currentListIndex;
- __GLXcontext *cx;
- int error;
-
- req = (xGLXUseXFontReq *) pc;
- cx = __glXForceCurrent(cl, req->contextTag, &error);
- if (!cx) {
- return error;
- }
-
- CALL_GetIntegerv( GET_DISPATCH(), (GL_LIST_INDEX, (GLint*) ¤tListIndex) );
- if (currentListIndex != 0) {
- /*
- ** A display list is currently being made. It is an error
- ** to try to make a font during another lists construction.
- */
- client->errorValue = cx->id;
- return __glXError(GLXBadContextState);
- }
-
- /*
- ** Font can actually be either the ID of a font or the ID of a GC
- ** containing a font.
- */
-
- error = dixLookupFontable(&pFont, req->font, client, DixReadAccess);
- if (error != Success)
- return error;
-
- return MakeBitmapsFromFont(pFont, req->first, req->count,
- req->listBase);
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "glxserver.h" +#include "glxutil.h" +#include "unpack.h" +#include "glapitable.h" +#include "glapi.h" +#include "glthread.h" +#include "dispatch.h" +#include "indirect_dispatch.h" +#include <GL/gl.h> +#include <pixmapstr.h> +#include <windowstr.h> +#include <dixfontstr.h> + +/* +** Make a single GL bitmap from a single X glyph +*/ +static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci) +{ + int i, j; + int widthPadded; /* width of glyph in bytes, as padded by X */ + int allocBytes; /* bytes to allocate to store bitmap */ + int w; /* width of glyph in bits */ + int h; /* height of glyph */ + register unsigned char *pglyph; + register unsigned char *p; + unsigned char *allocbuf; +#define __GL_CHAR_BUF_SIZE 2048 + unsigned char buf[__GL_CHAR_BUF_SIZE]; + + w = GLYPHWIDTHPIXELS(pci); + h = GLYPHHEIGHTPIXELS(pci); + widthPadded = GLYPHWIDTHBYTESPADDED(pci); + + /* + ** Use the local buf if possible, otherwise malloc. + */ + allocBytes = widthPadded * h; + if (allocBytes <= __GL_CHAR_BUF_SIZE) { + p = buf; + allocbuf = 0; + } else { + p = (unsigned char *) malloc(allocBytes); + if (!p) + return BadAlloc; + allocbuf = p; + } + + /* + ** We have to reverse the picture, top to bottom + */ + + pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h-1)*widthPadded; + for (j=0; j < h; j++) { + for (i=0; i < widthPadded; i++) { + p[i] = pglyph[i]; + } + pglyph -= widthPadded; + p += widthPadded; + } + CALL_Bitmap( GET_DISPATCH(), (w, h, -pci->metrics.leftSideBearing, + pci->metrics.descent, + pci->metrics.characterWidth, 0, + allocbuf ? allocbuf : buf) ); + + free(allocbuf); + return Success; +#undef __GL_CHAR_BUF_SIZE +} + +/* +** Create a GL bitmap for each character in the X font. The bitmap is stored +** in a display list. +*/ + +static int +MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base) +{ + unsigned long i, nglyphs; + CARD8 chs[2]; /* the font index we are going after */ + CharInfoPtr pci; + int rv; /* return value */ + int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit; + + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, FALSE) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, 0) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, GLYPHPADBYTES) ); + for (i=0; i < count; i++) { + chs[0] = (first + i) >> 8; /* high byte is first byte */ + chs[1] = first + i; + + (*pFont->get_glyphs)(pFont, 1, chs, (FontEncoding)encoding, + &nglyphs, &pci); + + /* + ** Define a display list containing just a glBitmap() call. + */ + CALL_NewList( GET_DISPATCH(), (list_base + i, GL_COMPILE) ); + if (nglyphs ) { + rv = __glXMakeBitmapFromGlyph(pFont, pci); + if (rv) { + return rv; + } + } + CALL_EndList( GET_DISPATCH(), () ); + } + return Success; +} + +/************************************************************************/ + +int __glXDisp_UseXFont(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXUseXFontReq *req; + FontPtr pFont; + GLuint currentListIndex; + __GLXcontext *cx; + int error; + + REQUEST_SIZE_MATCH(xGLXUseXFontReq); + + req = (xGLXUseXFontReq *) pc; + cx = __glXForceCurrent(cl, req->contextTag, &error); + if (!cx) { + return error; + } + + CALL_GetIntegerv( GET_DISPATCH(), (GL_LIST_INDEX, (GLint*) ¤tListIndex) ); + if (currentListIndex != 0) { + /* + ** A display list is currently being made. It is an error + ** to try to make a font during another lists construction. + */ + client->errorValue = cx->id; + return __glXError(GLXBadContextState); + } + + /* + ** Font can actually be either the ID of a font or the ID of a GC + ** containing a font. + */ + + error = dixLookupFontable(&pFont, req->font, client, DixReadAccess); + if (error != Success) + return error; + + return MakeBitmapsFromFont(pFont, req->first, req->count, + req->listBase); +} diff --git a/xorg-server/hw/dmx/Makefile.am b/xorg-server/hw/dmx/Makefile.am index 2a87c3966..e0b201b82 100644 --- a/xorg-server/hw/dmx/Makefile.am +++ b/xorg-server/hw/dmx/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS = input config examples doc +SUBDIRS = input config examples doc man bin_PROGRAMS = Xdmx if XINERAMA @@ -85,28 +85,5 @@ Xdmx_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) Xdmx_DEPENDENCIES= $(XDMX_LIBS) Xdmx_LDADD = $(XDMX_LIBS) $(XDMX_SYS_LIBS) $(XSERVER_SYS_LIBS) -# Man page -appmandir = $(APP_MAN_DIR) - -appman_PRE = Xdmx.man -appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) - -CLEANFILES = $(appman_DATA) - -# Strings to replace in man pages -XORGRELSTRING = @PACKAGE_STRING@ - XORGMANNAME = X Version 11 - -MAN_SUBSTS = \ - -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ - -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' - -SUFFIXES = .$(APP_MAN_SUFFIX) .man - -.man.$(APP_MAN_SUFFIX): - $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ - -EXTRA_DIST = $(appman_PRE) - relink: $(AM_V_at)rm -f Xdmx$(EXEEXT) && $(MAKE) Xdmx$(EXEEXT) diff --git a/xorg-server/hw/dmx/config/Makefile.am b/xorg-server/hw/dmx/config/Makefile.am index 25a814e79..de4ce315d 100644 --- a/xorg-server/hw/dmx/config/Makefile.am +++ b/xorg-server/hw/dmx/config/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = man + noinst_LIBRARIES = libdmxconfig.a LIBSRCS = parser.y \ @@ -53,26 +55,7 @@ dmxtodmx_DEPENDENCIES = libdmxconfig.a dmxtodmx_SOURCES = dmxtodmx.c dmxtodmx_LDADD = -L. -ldmxconfig -appmandir = $(APP_MAN_DIR) - -appman_PRE = xdmxconfig.man vdltodmx.man dmxtodmx.man -appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) - -CLEANFILES = $(appman_DATA) - -SUFFIXES = .$(APP_MAN_SUFFIX) .man - -# Strings to replace in man pages -XORGRELSTRING = @PACKAGE_STRING@ - XORGMANNAME = X Version 11 - -MAN_SUBSTS = -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' - -.man.$(APP_MAN_SUFFIX): - $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ - EXTRA_DIST = \ - $(appman_PRE) \ test-a.in test-a.out \ test-b.in test-b.out \ test-c.in test-c.out \ diff --git a/xorg-server/hw/dmx/config/man/Makefile.am b/xorg-server/hw/dmx/config/man/Makefile.am new file mode 100644 index 000000000..9bb62a4c6 --- /dev/null +++ b/xorg-server/hw/dmx/config/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +appman_PRE = xdmxconfig.man vdltodmx.man dmxtodmx.man diff --git a/xorg-server/hw/dmx/config/dmxtodmx.man b/xorg-server/hw/dmx/config/man/dmxtodmx.man index 68c7f5b40..68c7f5b40 100644 --- a/xorg-server/hw/dmx/config/dmxtodmx.man +++ b/xorg-server/hw/dmx/config/man/dmxtodmx.man diff --git a/xorg-server/hw/dmx/config/vdltodmx.man b/xorg-server/hw/dmx/config/man/vdltodmx.man index b733db7ab..b733db7ab 100644 --- a/xorg-server/hw/dmx/config/vdltodmx.man +++ b/xorg-server/hw/dmx/config/man/vdltodmx.man diff --git a/xorg-server/hw/dmx/config/xdmxconfig.man b/xorg-server/hw/dmx/config/man/xdmxconfig.man index dcceea0e3..dcceea0e3 100644 --- a/xorg-server/hw/dmx/config/xdmxconfig.man +++ b/xorg-server/hw/dmx/config/man/xdmxconfig.man diff --git a/xorg-server/hw/dmx/man/Makefile.am b/xorg-server/hw/dmx/man/Makefile.am new file mode 100644 index 000000000..e717aefe2 --- /dev/null +++ b/xorg-server/hw/dmx/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +appman_PRE = Xdmx.man diff --git a/xorg-server/hw/dmx/Xdmx.man b/xorg-server/hw/dmx/man/Xdmx.man index 9c8bdea00..9c8bdea00 100644 --- a/xorg-server/hw/dmx/Xdmx.man +++ b/xorg-server/hw/dmx/man/Xdmx.man diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.am b/xorg-server/hw/kdrive/ephyr/Makefile.am index 8646703ad..9d9b64ee5 100644 --- a/xorg-server/hw/kdrive/ephyr/Makefile.am +++ b/xorg-server/hw/kdrive/ephyr/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = man + INCLUDES = \ @KDRIVE_INCS@ \ @KDRIVE_CFLAGS@ \ @@ -83,20 +85,6 @@ Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) relink: $(AM_V_at)rm -f $(bin_PROGRAMS) && $(MAKE) $(bin_PROGRAMS) -MAN_SRCS = Xephyr.man.pre - -appmandir = $(APP_MAN_DIR) -appman_DATA = Xephyr.$(APP_MAN_SUFFIX) - -Xephyr.$(APP_MAN_SUFFIX): Xephyr.man - -$(AM_V_at)rm -f Xephyr.$(APP_MAN_SUFFIX) - $(AM_V_at)$(LN_S) Xephyr.man Xephyr.$(APP_MAN_SUFFIX) - -include $(top_srcdir)/cpprules.in - -CLEANFILES = $(appman_DATA) Xephyr.man - EXTRA_DIST = \ $(HOSTVIDEO_SRCS) \ - $(HOSTDRI_SRCS) \ - $(MAN_SRCS) + $(HOSTDRI_SRCS) diff --git a/xorg-server/hw/kdrive/ephyr/man/Makefile.am b/xorg-server/hw/kdrive/ephyr/man/Makefile.am new file mode 100644 index 000000000..e8a372143 --- /dev/null +++ b/xorg-server/hw/kdrive/ephyr/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +appman_PRE = Xephyr.man diff --git a/xorg-server/hw/kdrive/ephyr/Xephyr.man.pre b/xorg-server/hw/kdrive/ephyr/man/Xephyr.man index eb80b96b0..8e7bfd550 100644 --- a/xorg-server/hw/kdrive/ephyr/Xephyr.man.pre +++ b/xorg-server/hw/kdrive/ephyr/man/Xephyr.man @@ -46,9 +46,9 @@ sets the screen size. .BI -parent " id" uses exiting window .I id . -If a -.BI -screen -argument follows a +If a +.BI -screen +argument follows a .BI -parent argument, this screen is embedded into the given window. .TP 8 @@ -85,5 +85,3 @@ Mouse button 5 probably won't work. X(__miscmansuffix__), Xserver(__appmansuffix__) .SH AUTHOR Matthew Allum <mallum@o-hand.com> 2004 - - diff --git a/xorg-server/hw/vfb/Makefile.am b/xorg-server/hw/vfb/Makefile.am index f7a8c24af..ed46dbbc1 100644 --- a/xorg-server/hw/vfb/Makefile.am +++ b/xorg-server/hw/vfb/Makefile.am @@ -1,51 +1,34 @@ -bin_PROGRAMS = Xvfb
-noinst_LIBRARIES = libfbcmap.a
-
-AM_CFLAGS = -DHAVE_DIX_CONFIG_H \
- -DNO_HW_ONLY_EXTS \
- -DNO_MODULE_EXTS \
- $(XVFBMODULES_CFLAGS) \
- $(DIX_CFLAGS)
-
-SRCS = InitInput.c \
- InitOutput.c \
- $(top_srcdir)/Xext/dpmsstubs.c \
- $(top_srcdir)/Xi/stubs.c \
- $(top_srcdir)/mi/miinitext.c
-
-libfbcmap_a_CFLAGS = $(AM_CFLAGS)
-libfbcmap_a_SOURCES = $(top_srcdir)/fb/fbcmap_mi.c
-
-Xvfb_SOURCES = $(SRCS)
-
-XVFB_LIBS = \
- @XVFB_LIBS@ \
- libfbcmap.a \
- $(MAIN_LIB) \
- $(XSERVER_LIBS)
-
-Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS)
-Xvfb_DEPENDENCIES = $(XVFB_LIBS)
-Xvfb_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
-
-# Man page
-include $(top_srcdir)/cpprules.in
-
-appmandir = $(APP_MAN_DIR)
-
-appman_PRE = Xvfb.man
-appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@)
-
-BUILT_SOURCES = $(appman_PRE)
-CLEANFILES = $(appman_PRE) $(appman_DATA)
-
-SUFFIXES += .$(APP_MAN_SUFFIX) .man
-
-.man.$(APP_MAN_SUFFIX):
- -$(AM_V_at)rm -f $@
- $(AM_V_at)$(LN_S) $< $@
-
-EXTRA_DIST = Xvfb.man.pre
-
-relink:
- $(AM_V_at)rm -f Xvfb$(EXEEXT) && $(MAKE) Xvfb$(EXEEXT)
+SUBDIRS = man + +bin_PROGRAMS = Xvfb +noinst_LIBRARIES = libfbcmap.a + +AM_CFLAGS = -DHAVE_DIX_CONFIG_H \ + -DNO_HW_ONLY_EXTS \ + -DNO_MODULE_EXTS \ + $(XVFBMODULES_CFLAGS) \ + $(DIX_CFLAGS) + +SRCS = InitInput.c \ + InitOutput.c \ + $(top_srcdir)/Xext/dpmsstubs.c \ + $(top_srcdir)/Xi/stubs.c \ + $(top_srcdir)/mi/miinitext.c + +libfbcmap_a_CFLAGS = $(AM_CFLAGS) +libfbcmap_a_SOURCES = $(top_srcdir)/fb/fbcmap_mi.c + +Xvfb_SOURCES = $(SRCS) + +XVFB_LIBS = \ + @XVFB_LIBS@ \ + libfbcmap.a \ + $(MAIN_LIB) \ + $(XSERVER_LIBS) + +Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS) +Xvfb_DEPENDENCIES = $(XVFB_LIBS) +Xvfb_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) + +relink: + $(AM_V_at)rm -f Xvfb$(EXEEXT) && $(MAKE) Xvfb$(EXEEXT) diff --git a/xorg-server/hw/vfb/man/Makefile.am b/xorg-server/hw/vfb/man/Makefile.am new file mode 100644 index 000000000..93941882a --- /dev/null +++ b/xorg-server/hw/vfb/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +appman_PRE = Xvfb.man diff --git a/xorg-server/hw/vfb/Xvfb.man.pre b/xorg-server/hw/vfb/man/Xvfb.man index 569afe175..95b4dd4c1 100644 --- a/xorg-server/hw/vfb/Xvfb.man.pre +++ b/xorg-server/hw/vfb/man/Xvfb.man @@ -1,16 +1,16 @@ .\" $XdotOrg: xc/programs/Xserver/hw/vfb/Xvfb.man,v 1.3 2005/03/23 20:49:52 gisburn Exp $ .\" $Xorg: Xvfb.man,v 1.4 2001/02/09 02:04:45 xorgcvs Exp $ .\" Copyright 1993, 1998 The Open Group -.\" +.\" .\" Permission to use, copy, modify, distribute, and sell this software and its .\" documentation for any purpose is hereby granted without fee, provided that .\" the above copyright notice appear in all copies and that both that .\" copyright notice and this permission notice appear in supporting .\" documentation. -.\" +.\" .\" 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. @@ -18,7 +18,7 @@ .\" 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. -.\" +.\" .\" Except as contained in this notice, the name of The Open Group shall .\" not be used in advertising or otherwise to promote the sale, use or .\" other dealings in this Software without prior written authorization @@ -66,7 +66,7 @@ have values from 1 to 32. .B "\-fbdir \fIframebuffer-directory\fP" This option specifies the directory in which the memory mapped files containing the framebuffer memory should be created. -See FILES. +See FILES. This option only exists on machines that have the mmap and msync system calls. .TP 4 @@ -113,7 +113,7 @@ Xvfb -pixdepths 3 27 -fbdir /var/tmp The server will listen for connections as server number 0, will have the default screen configuration (one screen, 1280x1024x8), will also support pixmap -depths of 3 and 27, +depths of 3 and 27, and will use memory mapped files in /var/tmp for the framebuffer. .TP 8 xwud -in /var/tmp/Xvfb_screen0 diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index c948afdcf..c23b1fd6c 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -1,120 +1,120 @@ -include $(top_srcdir)/cpprules.in
-
-if DRI
-DRI_SUBDIR = dri
-endif
-
-if DRI2
-DRI2_SUBDIR = dri2
-endif
-
-if XF86UTILS
-XF86UTILS_SUBDIR = utils
-endif
-
-if XAA
-XAA_SUBDIR = xaa
-endif
-
-if VGAHW
-VGAHW_SUBDIR = vgahw
-endif
-
-if VBE
-VBE_SUBDIR = vbe
-endif
-
-if INT10MODULE
-INT10_SUBDIR = int10
-endif
-
-DOC_SUBDIR = doc
-
-SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \
- ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
- loader dixmods exa modes \
- $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) $(DOC_SUBDIR)
-
-DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
- parser ramdac shadowfb vbe vgahw xaa \
- loader dixmods dri dri2 exa modes \
- utils doc
-
-bin_PROGRAMS = Xorg
-Xorg_SOURCES = xorg.c
-
-AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-INCLUDES = @XORG_INCS@
-
-noinst_LTLIBRARIES = libxorg.la
-libxorg_la_SOURCES = libxorg.c
-libxorg_la_LIBADD = \
- $(XSERVER_LIBS) \
- loader/libloader.la \
- os-support/libxorgos.la \
- common/libcommon.la \
- parser/libxf86config_internal.la \
- dixmods/libdixmods.la \
- modes/libxf86modes.la \
- ramdac/libramdac.la \
- ddc/libddc.la \
- i2c/libi2c.la \
- dixmods/libxorgxkb.la \
- $(top_builddir)/mi/libmi.la \
- $(top_builddir)/os/libos.la \
- @XORG_LIBS@
-
-libxorg_la_DEPENDENCIES = $(libxorg_la_LIBADD)
-
-libxorg.c xorg.c:
- touch $@
-
-DISTCLEANFILES = libxorg.c xorg.c
-
-Xorg_DEPENDENCIES = libxorg.la
-Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS)
-
-Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
-
-BUILT_SOURCES = xorg.conf.example
-DISTCLEANFILES += xorg.conf.example xorg.conf.example.pre
-EXTRA_DIST = xorgconf.cpp
-
-if SPECIAL_DTRACE_OBJECTS
-# Re-add dtrace object code that gets lost when building static libraries
-Xorg_LDADD += $(XSERVER_LIBS)
-endif
-
-if SOLARIS_ASM_INLINE
-# Needs to be built before any files are compiled when using Sun compilers
-# so in*/out* inline definitions are properly processed.
-
-BUILT_SOURCES += os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il
-
-os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il:
- cd os-support/solaris ; \
- $(MAKE) $(AM_MAKEFLAGS) solaris-@SOLARIS_INOUT_ARCH@.il
-endif
-
-# do not use $(mkdir_p) if you want automake 1.7 to work
-install-data-local:
- mkdir -p $(DESTDIR)$(logdir)
-
-
-install-exec-local: install-binPROGRAMS
- (cd $(DESTDIR)$(bindir) && rm -f X && ln -s Xorg X)
-if INSTALL_SETUID
- chown root $(DESTDIR)$(bindir)/Xorg
- chmod u+s $(DESTDIR)$(bindir)/Xorg
-endif
-
-CPP_FILES_FLAGS = \
- $(MANDEFS) \
- -DDEFAULTFONTPATH="\"$(COMPILEDDEFAULTFONTPATH)\"" \
- -DMODULEPATH=\"$(DEFAULT_MODULE_PATH)\"
-
-relink:
- $(AM_V_at)rm -f Xorg && $(MAKE) Xorg
-
-xorg.conf.example.pre: xorgconf.cpp
- cp $(srcdir)/xorgconf.cpp $@
+ +if DRI +DRI_SUBDIR = dri +endif + +if DRI2 +DRI2_SUBDIR = dri2 +endif + +if XF86UTILS +XF86UTILS_SUBDIR = utils +endif + +if XAA +XAA_SUBDIR = xaa +endif + +if VGAHW +VGAHW_SUBDIR = vgahw +endif + +if VBE +VBE_SUBDIR = vbe +endif + +if INT10MODULE +INT10_SUBDIR = int10 +endif + +DOC_SUBDIR = doc + +SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \ + ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ + loader dixmods exa modes \ + $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) $(DOC_SUBDIR) + +DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ + parser ramdac shadowfb vbe vgahw xaa \ + loader dixmods dri dri2 exa modes \ + utils doc + +bin_PROGRAMS = Xorg +Xorg_SOURCES = xorg.c + +AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@ +INCLUDES = @XORG_INCS@ + +noinst_LTLIBRARIES = libxorg.la +libxorg_la_SOURCES = libxorg.c +libxorg_la_LIBADD = \ + $(XSERVER_LIBS) \ + loader/libloader.la \ + os-support/libxorgos.la \ + common/libcommon.la \ + parser/libxf86config_internal.la \ + dixmods/libdixmods.la \ + modes/libxf86modes.la \ + ramdac/libramdac.la \ + ddc/libddc.la \ + i2c/libi2c.la \ + dixmods/libxorgxkb.la \ + $(top_builddir)/mi/libmi.la \ + $(top_builddir)/os/libos.la \ + @XORG_LIBS@ + +libxorg_la_DEPENDENCIES = $(libxorg_la_LIBADD) + +libxorg.c xorg.c: + touch $@ + +DISTCLEANFILES = libxorg.c xorg.c + +Xorg_DEPENDENCIES = libxorg.la +Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) + +Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) + +BUILT_SOURCES = xorg.conf.example +DISTCLEANFILES += xorg.conf.example +EXTRA_DIST = xorgconf.cpp + +if SPECIAL_DTRACE_OBJECTS +# Re-add dtrace object code that gets lost when building static libraries +Xorg_LDADD += $(XSERVER_LIBS) +endif + +if SOLARIS_ASM_INLINE +# Needs to be built before any files are compiled when using Sun compilers +# so in*/out* inline definitions are properly processed. + +BUILT_SOURCES += os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il + +os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il: + cd os-support/solaris ; \ + $(MAKE) $(AM_MAKEFLAGS) solaris-@SOLARIS_INOUT_ARCH@.il +endif + +# do not use $(mkdir_p) if you want automake 1.7 to work +install-data-local: + mkdir -p $(DESTDIR)$(logdir) + + +install-exec-local: install-binPROGRAMS + (cd $(DESTDIR)$(bindir) && rm -f X && ln -s Xorg X) +if INSTALL_SETUID + chown root $(DESTDIR)$(bindir)/Xorg + chmod u+s $(DESTDIR)$(bindir)/Xorg +endif + +# Use variables from XORG_MANPAGE_SECTIONS and X Server configuration +# Do not include manpages.am as values are not appropriate for rc files +CONF_SUBSTS = -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' \ + -e 's|MODULEPATH|$(DEFAULT_MODULE_PATH)|g' \ + -e 's|DEFAULTFONTPATH|$(COMPILEDDEFAULTFONTPATH)|g' + +xorg.conf.example: xorgconf.cpp + $(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $< > $@ + +relink: + $(AM_V_at)rm -f Xorg && $(MAKE) Xorg diff --git a/xorg-server/hw/xfree86/doc/man/Makefile.am b/xorg-server/hw/xfree86/doc/man/Makefile.am index 737166b51..fe330a72c 100644 --- a/xorg-server/hw/xfree86/doc/man/Makefile.am +++ b/xorg-server/hw/xfree86/doc/man/Makefile.am @@ -1,24 +1,3 @@ -# Xserver.man covers options generic to all X servers built in this tree -MAN_SRCS = Xorg.man.pre xorg.conf.man.pre - -appmandir = $(APP_MAN_DIR) -appman_DATA = Xorg.$(APP_MAN_SUFFIX) - -filemandir = $(FILE_MAN_DIR) -fileman_DATA = xorg.conf.$(FILE_MAN_SUFFIX) - -Xorg.$(APP_MAN_SUFFIX): Xorg.man - -$(AM_V_at)rm -f Xorg.$(APP_MAN_SUFFIX) - $(AM_V_at)$(LN_S) Xorg.man Xorg.$(APP_MAN_SUFFIX) - -xorg.conf.$(FILE_MAN_SUFFIX): xorg.conf.man - -$(AM_V_at)rm -f xorg.conf.$(FILE_MAN_SUFFIX) - $(AM_V_at)$(LN_S) xorg.conf.man xorg.conf.$(FILE_MAN_SUFFIX) - -include $(top_srcdir)/cpprules.in - -EXTRAMANDEFS = -D__logdir__=$(logdir) - -CLEANFILES = $(appman_DATA) $(fileman_DATA) xorg.conf.man Xorg.man - -EXTRA_DIST = $(MAN_SRCS) +include $(top_srcdir)/manpages.am +appman_PRE = Xorg.man +fileman_PRE = xorg.conf.man diff --git a/xorg-server/hw/xfree86/doc/man/Xorg.man.pre b/xorg-server/hw/xfree86/doc/man/Xorg.man index c497a0e8c..6fa334cc3 100644 --- a/xorg-server/hw/xfree86/doc/man/Xorg.man.pre +++ b/xorg-server/hw/xfree86/doc/man/Xorg.man @@ -1,689 +1,689 @@ -.\" $XdotOrg: xserver/xorg/hw/xfree86/doc/man/Xorg.man.pre,v 1.3 2005/07/04 18:41:01 ajax Exp $
-.\" shorthand for double quote that works everywhere.
-.ds q \N'34'
-.TH __xservername__ __appmansuffix__ __vendorversion__
-.SH NAME
-__xservername__ - X11R7 X server
-.SH SYNOPSIS
-.B __xservername__
-.RI [\fB:\fP display ]
-.RI [ option
-.IR ... ]
-.SH DESCRIPTION
-.B __xservername__
-is a full featured X server that was originally designed for UNIX and
-UNIX-like operating systems running on Intel x86 hardware. It now runs
-on a wider range of hardware and OS platforms.
-.PP
-This work was derived by the X.Org Foundation from the XFree86 Project's
-.I "XFree86\ 4.4rc2"
-release.
-The XFree86 release was originally derived from
-.I "X386\ 1.2"
-by Thomas Roell which was contributed to X11R5 by Snitily Graphics
-Consulting Service.
-.SH PLATFORMS
-.PP
-.B __xservername__
-operates under a wide range of operating systems and hardware platforms.
-The Intel x86 (IA32) architecture is the most widely supported hardware
-platform. Other hardware platforms include Compaq Alpha, Intel IA64, AMD64,
-SPARC and PowerPC. The most widely supported operating systems are the
-free/OpenSource UNIX-like systems such as Linux, FreeBSD, NetBSD,
-OpenBSD, and Solaris. Commercial UNIX operating systems such as
-UnixWare are also supported. Other supported operating systems include
-GNU Hurd. Mac OS X is supported with the
-Xquartz(__appmansuffix__) X server. Win32/Cygwin is supported with the
-XWin(__appmansuffix__) X server.
-.PP
-.SH "NETWORK CONNECTIONS"
-.B __xservername__
-supports connections made using the following reliable
-byte-streams:
-.TP 4
-.I "Local"
-On most platforms, the "Local" connection type is a UNIX-domain socket.
-On some System V platforms, the "local" connection types also include
-STREAMS pipes, named pipes, and some other mechanisms.
-.TP 4
-.I TCP\/IP
-.B __xservername__
-listens on port
-.RI 6000+ n ,
-where
-.I n
-is the display number. This connection type can be disabled with the
-.B \-nolisten
-option (see the Xserver(1) man page for details).
-.SH "ENVIRONMENT VARIABLES"
-For operating systems that support local connections other than Unix
-Domain sockets (SVR3 and SVR4), there is a compiled-in list specifying
-the order in which local connections should be attempted. This list
-can be overridden by the
-.I XLOCAL
-environment variable described below. If the display name indicates a
-best-choice connection should be made (e.g.
-.BR :0.0 ),
-each connection mechanism is tried until a connection succeeds or no
-more mechanisms are available. Note: for these OSs, the Unix Domain
-socket connection is treated differently from the other local connection
-types. To use it the connection must be made to
-.BR unix:0.0 .
-.PP
-The
-.I XLOCAL
-environment variable should contain a list of one more
-more of the following:
-.PP
-.RS 8
-.nf
-NAMED
-PTS
-SCO
-ISC
-.fi
-.RE
-.PP
-which represent SVR4 Named Streams pipe, Old-style USL Streams pipe,
-SCO XSight Streams pipe, and ISC Streams pipe, respectively. You can
-select a single mechanism (e.g.
-.IR XLOCAL=NAMED ),
-or an ordered list (e.g. \fIXLOCAL="NAMED:PTS:SCO"\fP).
-his variable overrides the compiled-in defaults. For SVR4 it is
-recommended that
-.I NAMED
-be the first preference connection. The default setting is
-.IR PTS:NAMED:ISC:SCO .
-.PP
-To globally override the compiled-in defaults, you should define (and
-export if using
-.B sh
-or
-.BR ksh )
-.I XLOCAL
-globally. If you use startx(1) or xinit(1), the definition should be
-at the top of your
-.I .xinitrc
-file. If you use xdm(1), the definitions should be early on in the
-.I __projectroot__/lib/X11/xdm/Xsession
-script.
-.SH OPTIONS
-.B __xservername__
-supports several mechanisms for supplying/obtaining configuration and
-run-time parameters: command line options, environment variables, the
-__xconfigfile__(__filemansuffix__) configuration files, auto-detection, and
-fallback defaults. When the same information is supplied in more than
-one way, the highest precedence mechanism is used. The list of mechanisms
-is ordered from highest precedence to lowest. Note that not all parameters
-can be supplied via all methods. The available command line options
-and environment variables (and some defaults) are described here and in
-the Xserver(__appmansuffix__) manual page. Most configuration file
-parameters, with their defaults, are described in the
-__xconfigfile__(__filemansuffix__) manual page. Driver and module specific
-configuration parameters are described in the relevant driver or module
-manual page.
-.PP
-In addition to the normal server options described in the
-Xserver(__appmansuffix__) manual page,
-.B __xservername__
-accepts the following command line switches:
-.TP 8
-.BI vt XX
-.I XX
-specifies the Virtual Terminal device number which
-.B __xservername__
-will use. Without this option,
-.B __xservername__
-will pick the first available Virtual Terminal that it can locate. This
-option applies only to platforms that have virtual terminal support, such
-as Linux, BSD, OpenSolaris, SVR3, and SVR4.
-.TP
-.B \-allowMouseOpenFail
-Allow the server to start up even if the mouse device can't be opened
-or initialised. This is equivalent to the
-.B AllowMouseOpenFail
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B \-allowNonLocalXvidtune
-Make the VidMode extension available to remote clients. This allows
-the xvidtune client to connect from another host. This is equivalent
-to the
-.B AllowNonLocalXvidtune
-__xconfigfile__(__filemansuffix__) file option. By default non-local
-connections are not allowed.
-.TP 8
-.BI \-bgamma " value"
-Set the blue gamma correction.
-.I value
-must be between 0.1 and 10.
-The default is 1.0. Not all drivers support this. See also the
-.BR \-gamma ,
-.BR \-rgamma ,
-and
-.B \-ggamma
-options.
-.TP 8
-.BI \-bpp " n"
-No longer supported. Use
-.B \-depth
-to set the color depth, and use
-.B \-fbbpp
-if you really need to force a non-default framebuffer (hardware) pixel
-format.
-.TP 8
-.BI \-config " file"
-Read the server configuration from
-.IR file .
-This option will work for any file when the server is run as root (i.e,
-with real-uid 0), or for files relative to a directory in the config
-search path for all other users.
-.TP 8
-.BI \-configdir " directory"
-Read the server configuration files from
-.IR directory .
-This option will work for any directory when the server is run as root
-(i.e, with real-uid 0), or for directories relative to a directory in the
-config directory search path for all other users.
-.TP 8
-.B \-configure
-When this option is specified, the
-.B __xservername__
-server loads all video driver modules, probes for available hardware,
-and writes out an initial __xconfigfile__(__filemansuffix__) file based on
-what was detected. This option currently has some problems on some
-platforms, but in most cases it is a good way to bootstrap the
-configuration process. This option is only available when the server
-is run as root (i.e, with real-uid 0).
-.TP 8
-.BI "\-crt /dev/tty" XX
-SCO only. This is the same as the
-.B vt
-option, and is provided for compatibility with the native SCO X server.
-.TP 8
-.BI \-depth " n"
-Sets the default color depth. Legal values are 1, 4, 8, 15, 16, and
-24. Not all drivers support all values.
-.TP 8
-.B \-disableVidMode
-Disable the parts of the VidMode extension (used by the xvidtune
-client) that can be used to change the video modes. This is equivalent
-to the
-.B DisableVidModeExtension
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B \-fbbpp \fIn\fP
-Sets the number of framebuffer bits per pixel. You should only set this
-if you're sure it's necessary; normally the server can deduce the correct
-value from
-.B \-depth
-above. Useful if you want to run a depth 24 configuration with a 24
-bpp framebuffer rather than the (possibly default) 32 bpp framebuffer
-(or vice versa). Legal values are 1, 8, 16, 24, 32. Not all drivers
-support all values.
-.TP 8
-.B \-flipPixels
-Swap the default values for the black and white pixels.
-.TP 8
-.BI \-gamma " value"
-Set the gamma correction.
-.I value
-must be between 0.1 and 10. The default is 1.0. This value is applied
-equally to the R, G and B values. Those values can be set independently
-with the
-.BR \-rgamma ,
-.BR \-bgamma ,
-and
-.B \-ggamma
-options. Not all drivers support this.
-.TP 8
-.BI \-ggamma " value"
-Set the green gamma correction.
-.I value
-must be between 0.1 and 10. The default is 1.0. Not all drivers support
-this. See also the
-.BR \-gamma ,
-.BR \-rgamma ,
-and
-.B \-bgamma
-options.
-.TP 8
-.B \-ignoreABI
-The
-.B __xservername__
-server checks the ABI revision levels of each module that it loads. It
-will normally refuse to load modules with ABI revisions that are newer
-than the server's. This is because such modules might use interfaces
-that the server does not have. When this option is specified, mismatches
-like this are downgraded from fatal errors to warnings. This option
-should be used with care.
-.TP 8
-.B \-isolateDevice \fIbus\-id\fP
-Restrict device resets to the device at
-.IR bus\-id .
-The
-.I bus\-id
-string has the form
-.IB bustype : bus : device : function
-(e.g., \(oqPCI:1:0:0\(cq).
-At present, only isolation of PCI devices is supported; i.e., this option
-is ignored if
-.I bustype
-is anything other than \(oqPCI\(cq.
-.TP 8
-.B \-keeptty
-Prevent the server from detaching its initial controlling terminal.
-This option is only useful when debugging the server. Not all platforms
-support (or can use) this option.
-.TP 8
-.BI \-keyboard " keyboard-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B InputDevice
-section called
-.I keyboard-name
-as the core keyboard. This option is ignored when the
-.B Layout
-section specifies a core keyboard. In the absence of both a Layout
-section and this option, the first relevant
-.B InputDevice
-section is used for the core keyboard.
-.TP 8
-.BI \-layout " layout-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B Layout
-section called
-.IR layout-name .
-By default the first
-.B Layout
-section is used.
-.TP 8
-.BI \-logfile " filename"
-Use the file called
-.I filename
-as the
-.B __xservername__
-server log file. The default log file is
-.BI __logdir__/__xservername__. n .log
-on most platforms, where
-.I n
-is the display number of the
-.B __xservername__
-server. The default may be in a different directory on some platforms.
-This option is only available when the server is run as root (i.e, with
-real-uid 0).
-.TP 8
-.BR \-logverbose " [\fIn\fP]"
-Sets the verbosity level for information printed to the
-.B __xservername__
-server log file. If the
-.I n
-value isn't supplied, each occurrence of this option increments the log
-file verbosity level. When the
-.I n
-value is supplied, the log file verbosity level is set to that value.
-The default log file verbosity level is 3.
-.TP 8
-.BI \-modulepath " searchpath"
-Set the module search path to
-.IR searchpath .
-.I searchpath
-is a comma separated list of directories to search for
-.B __xservername__
-server modules. This option is only available when the server is run
-as root (i.e, with real-uid 0).
-.TP 8
-.B \-nosilk
-Disable Silken Mouse support.
-.TP 8
-.B \-pixmap24
-Set the internal pixmap format for depth 24 pixmaps to 24 bits per pixel.
-The default is usually 32 bits per pixel. There is normally little
-reason to use this option. Some client applications don't like this
-pixmap format, even though it is a perfectly legal format. This is
-equivalent to the
-.B Pixmap
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B \-pixmap32
-Set the internal pixmap format for depth 24 pixmaps to 32 bits per pixel.
-This is usually the default. This is equivalent to the
-.B Pixmap
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.BI \-pointer " pointer-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B InputDevice
-section called
-.I pointer-name
-as the core pointer. This option is ignored when the
-.B Layout
-section specifies a core pointer. In the absence of both a Layout
-section and this option, the first relevant
-.B InputDevice
-section is used for the core pointer.
-.TP 8
-.B \-quiet
-Suppress most informational messages at startup. The verbosity level
-is set to zero.
-.TP 8
-.BI \-rgamma " value"
-Set the red gamma correction.
-.I value
-must be between 0.1 and 10. The default is 1.0. Not all drivers support
-this. See also the
-.BR \-gamma ,
-.BR \-bgamma ,
-and
-.B \-ggamma
-options.
-.TP 8
-.BI \-screen " screen-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B Screen
-section called
-.IR screen-name .
-By default the screens referenced by the default
-.B Layout
-section are used, or the first
-.B Screen
-section when there are no
-.B Layout
-sections.
-.TP 8
-.B \-showconfig
-This is the same as the
-.B \-version
-option, and is included for compatibility reasons. It may be removed
-in a future release, so the
-.B \-version
-option should be used instead.
-.TP 8
-.B \-showDefaultModulePath
-Print out the default module path the server was compiled with.
-.TP 8
-.B \-showDefaultLibPath
-Print out the path libraries should be installed to.
-.TP 8
-.B \-showopts
-For each driver module installed, print out the list of options and their
-argument types.
-.TP 8
-.BI \-weight " nnn"
-Set RGB weighting at 16 bpp. The default is 565. This applies only to
-those drivers which support 16 bpp.
-.TP 8
-.BR \-verbose " [\fIn\fP]"
-Sets the verbosity level for information printed on stderr. If the
-.I n
-value isn't supplied, each occurrence of this option increments the
-verbosity level. When the
-.I n
-value is supplied, the verbosity level is set to that value. The default
-verbosity level is 0.
-.TP 8
-.B \-version
-Print out the server version, patchlevel, release date, the operating
-system/platform it was built on, and whether it includes module loader
-support.
-.SH "KEYBOARD"
-.PP
-The
-.B __xservername__
-server is normally configured to recognize various special combinations
-of key presses that instruct the server to perform some action, rather
-than just sending the key press event to a client application. These actions
-depend on the XKB keymap loaded by a particular keyboard device and may or
-may not be available on a given configuration.
-.PP
-The following key combinations are commonly part of the default XKEYBOARD
-keymap.
-.TP 8
-.B Ctrl+Alt+Backspace
-Immediately kills the server -- no questions asked. It can be disabled by
-setting the
-.B DontZap
-__xconfigfile__(__filemansuffix__) file option to a TRUE value.
-.PP
-.RS 8
-It should be noted that zapping is triggered by the
-.B Terminate_Server
-action in the keyboard map. This action is not part of the default keymaps
-but can be enabled with the XKB option
-.B \*qterminate:ctrl_alt_bksp\*q.
-.RE
-.TP 8
-.B Ctrl+Alt+Keypad-Plus
-Change video mode to next one specified in the configuration file.
-This can be disabled with the
-.B DontZoom
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B Ctrl+Alt+Keypad-Minus
-Change video mode to previous one specified in the configuration file.
-This can be disabled with the
-.B DontZoom
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B Ctrl+Alt+F1...F12
-For systems with virtual terminal support, these keystroke
-combinations are used to switch to virtual terminals 1 through 12,
-respectively. This can be disabled with the
-.B DontVTSwitch
-__xconfigfile__(__filemansuffix__) file option.
-.SH CONFIGURATION
-.B __xservername__
-typically uses a configuration file called
-.B __xconfigfile__
-and configuration files with the suffix
-.I .conf
-in a directory called
-.B __xconfigdir__
-for its initial setup.
-Refer to the __xconfigfile__(__filemansuffix__) manual page for information
-about the format of this file.
-.PP
-.B __xservername__
-has a mechanism for automatically generating a built-in configuration
-at run-time when no
-.B __xconfigfile__
-file or
-.B __xconfigdir__
-files are present. The current version of this automatic configuration
-mechanism works in two ways.
-.PP
-The first is via enhancements that have made many components of the
-.B __xconfigfile__
-file optional. This means that information that can be probed or
-reasonably deduced doesn't need to be specified explicitly, greatly
-reducing the amount of built-in configuration information that needs to
-be generated at run-time.
-.PP
-The second is to have "safe" fallbacks for most configuration information.
-This maximises the likelihood that the
-.B __xservername__
-server will start up in some usable configuration even when information
-about the specific hardware is not available.
-.PP
-The automatic configuration support for __xservername__ is work in progress.
-It is currently aimed at the most popular hardware and software platforms
-supported by __xservername__. Enhancements are planned for future releases.
-.SH FILES
-The
-.B __xservername__
-server config files can be found in a range of locations. These are
-documented fully in the __xconfigfile__(__filemansuffix__) manual page. The
-most commonly used locations are shown here.
-.TP 30
-.B /etc/X11/__xconfigfile__
-Server configuration file.
-.TP 30
-.B /etc/X11/__xconfigfile__-4
-Server configuration file.
-.TP 30
-.B /etc/__xconfigfile__
-Server configuration file.
-.TP 30
-.B __projectroot__/etc/__xconfigfile__
-Server configuration file.
-.TP 30
-.B __projectroot__/lib/X11/__xconfigfile__
-Server configuration file.
-.TP 30
-.B /etc/X11/__xconfigdir__
-Server configuration directory.
-.TP 30
-.B /etc/X11/__xconfigdir__-4
-Server configuration directory.
-.TP 30
-.B /etc/__xconfigdir__
-Server configuration directory.
-.TP 30
-.B __projectroot__/etc/__xconfigdir__
-Server configuration directory.
-.TP 30
-.B __projectroot__/lib/X11/__xconfigdir__
-Server configuration directory.
-.TP 30
-.BI __logdir__/__xservername__. n .log
-Server log file for display
-.IR n .
-.TP 30
-.B __projectroot__/bin/\(**
-Client binaries.
-.TP 30
-.B __projectroot__/include/\(**
-Header files.
-.TP 30
-.B __projectroot__/lib/\(**
-Libraries.
-.TP 30
-.B __datadir__/fonts/X11/\(**
-Fonts.
-.TP 30
-.B __projectroot__/share/X11/XErrorDB
-Client error message database.
-.TP 30
-.B __projectroot__/lib/X11/app-defaults/\(**
-Client resource specifications.
-.TP 30
-.B __mandir__/man?/\(**
-Manual pages.
-.TP 30
-.BI /etc/X n .hosts
-Initial access control list for display
-.IR n .
-.SH "SEE ALSO"
-X(__miscmansuffix__), Xserver(__appmansuffix__), xdm(__appmansuffix__), xinit(__appmansuffix__),
-__xconfigfile__(__filemansuffix__), xvidtune(__appmansuffix__),
-apm(__drivermansuffix__),
-ati(__drivermansuffix__),
-chips(__drivermansuffix__),
-cirrus(__drivermansuffix__),
-cyrix(__drivermansuffix__),
-fbdev(__drivermansuffix__),
-glide(__drivermansuffix__),
-glint(__drivermansuffix__),
-i128(__drivermansuffix__),
-i740(__drivermansuffix__),
-imstt(__drivermansuffix__),
-intel(__drivermansuffix__),
-mga(__drivermansuffix__),
-neomagic(__drivermansuffix__),
-nsc(__drivermansuffix__),
-nv(__drivermansuffix__),
-openchrome (__drivermansuffix__),
-r128(__drivermansuffix__),
-rendition(__drivermansuffix__),
-s3virge(__drivermansuffix__),
-siliconmotion(__drivermansuffix__),
-sis(__drivermansuffix__),
-sunbw2(__drivermansuffix__),
-suncg14(__drivermansuffix__),
-suncg3(__drivermansuffix__),
-suncg6(__drivermansuffix__),
-sunffb(__drivermansuffix__),
-sunleo(__drivermansuffix__),
-suntcx(__drivermansuffix__),
-tdfx(__drivermansuffix__),
-tga(__drivermansuffix__),
-trident(__drivermansuffix__),
-tseng(__drivermansuffix__),
-v4l(__drivermansuffix__),
-vesa(__drivermansuffix__),
-vmware(__drivermansuffix__),
-.br
-Web site
-.IR <http://www.x.org> .
-
-.SH AUTHORS
-__xservername__ has many contributors world wide. The names of most of them
-can be found in the documentation, ChangeLog files in the source tree,
-and in the actual source code.
-.PP
-__xservername__ was originally based on XFree86 4.4rc2.
-That was originally based on \fIX386 1.2\fP by Thomas Roell, which
-was contributed to the then X Consortium's X11R5 distribution by SGCS.
-.PP
-__xservername__ is released by the X.Org Foundation.
-.PP
-The project that became XFree86 was originally founded in 1992 by
-David Dawes, Glenn Lai, Jim Tsillas and David Wexelblat.
-.PP
-XFree86 was later integrated in the then X Consortium's X11R6 release
-by a group of dedicated XFree86 developers, including the following:
-.PP
-.RS 4
-.nf
-Stuart Anderson \fIanderson@metrolink.com\fP
-Doug Anson \fIdanson@lgc.com\fP
-Gertjan Akkerman \fIakkerman@dutiba.twi.tudelft.nl\fP
-Mike Bernson \fImike@mbsun.mlb.org\fP
-Robin Cutshaw \fIrobin@XFree86.org\fP
-David Dawes \fIdawes@XFree86.org\fP
-Marc Evans \fImarc@XFree86.org\fP
-Pascal Haible \fIhaible@izfm.uni-stuttgart.de\fP
-Matthieu Herrb \fIMatthieu.Herrb@laas.fr\fP
-Dirk Hohndel \fIhohndel@XFree86.org\fP
-David Holland \fIdavidh@use.com\fP
-Alan Hourihane \fIalanh@fairlite.demon.co.uk\fP
-Jeffrey Hsu \fIhsu@soda.berkeley.edu\fP
-Glenn Lai \fIglenn@cs.utexas.edu\fP
-Ted Lemon \fImellon@ncd.com\fP
-Rich Murphey \fIrich@XFree86.org\fP
-Hans Nasten \fInasten@everyware.se\fP
-Mark Snitily \fImark@sgcs.com\fP
-Randy Terbush \fIrandyt@cse.unl.edu\fP
-Jon Tombs \fItombs@XFree86.org\fP
-Kees Verstoep \fIversto@cs.vu.nl\fP
-Paul Vixie \fIpaul@vix.com\fP
-Mark Weaver \fIMark_Weaver@brown.edu\fP
-David Wexelblat \fIdwex@XFree86.org\fP
-Philip Wheatley \fIPhilip.Wheatley@ColumbiaSC.NCR.COM\fP
-Thomas Wolfram \fIwolf@prz.tu-berlin.de\fP
-Orest Zborowski \fIorestz@eskimo.com\fP
-.fi
-.RE
-.PP
-__xservername__ source is available from the FTP server
-\fI<ftp://ftp.x.org/>\fP, and from the X.Org
-server \fI<http://gitweb.freedesktop.org/>\fP. Documentation and other
-information can be found from the X.Org web site
-\fI<http://www.x.org/>\fP.
-
-.SH LEGAL
-.PP
-.B __xservername__
-is copyright software, provided under licenses that permit modification
-and redistribution in source and binary form without fee.
-.B __xservername__ is copyright by numerous authors and
-contributors from around the world. Licensing information can be found
-at
-.IR <http://www.x.org> .
-Refer to the source code for specific copyright notices.
-.PP
-.B XFree86(TM)
-is a trademark of The XFree86 Project, Inc.
-.PP
-.B X11(TM)
-and
-.B X Window System(TM)
-are trademarks of The Open Group.
+.\" $XdotOrg: xserver/xorg/hw/xfree86/doc/man/Xorg.man.pre,v 1.3 2005/07/04 18:41:01 ajax Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH __xservername__ __appmansuffix__ __vendorversion__ +.SH NAME +__xservername__ - X11R7 X server +.SH SYNOPSIS +.B __xservername__ +.RI [\fB:\fP display ] +.RI [ option +.IR ... ] +.SH DESCRIPTION +.B __xservername__ +is a full featured X server that was originally designed for UNIX and +UNIX-like operating systems running on Intel x86 hardware. It now runs +on a wider range of hardware and OS platforms. +.PP +This work was derived by the X.Org Foundation from the XFree86 Project's +.I "XFree86\ 4.4rc2" +release. +The XFree86 release was originally derived from +.I "X386\ 1.2" +by Thomas Roell which was contributed to X11R5 by Snitily Graphics +Consulting Service. +.SH PLATFORMS +.PP +.B __xservername__ +operates under a wide range of operating systems and hardware platforms. +The Intel x86 (IA32) architecture is the most widely supported hardware +platform. Other hardware platforms include Compaq Alpha, Intel IA64, AMD64, +SPARC and PowerPC. The most widely supported operating systems are the +free/OpenSource UNIX-like systems such as Linux, FreeBSD, NetBSD, +OpenBSD, and Solaris. Commercial UNIX operating systems such as +UnixWare are also supported. Other supported operating systems include +GNU Hurd. Mac OS X is supported with the +Xquartz(__appmansuffix__) X server. Win32/Cygwin is supported with the +XWin(__appmansuffix__) X server. +.PP +.SH "NETWORK CONNECTIONS" +.B __xservername__ +supports connections made using the following reliable +byte-streams: +.TP 4 +.I "Local" +On most platforms, the "Local" connection type is a UNIX-domain socket. +On some System V platforms, the "local" connection types also include +STREAMS pipes, named pipes, and some other mechanisms. +.TP 4 +.I TCP\/IP +.B __xservername__ +listens on port +.RI 6000+ n , +where +.I n +is the display number. This connection type can be disabled with the +.B \-nolisten +option (see the Xserver(1) man page for details). +.SH "ENVIRONMENT VARIABLES" +For operating systems that support local connections other than Unix +Domain sockets (SVR3 and SVR4), there is a compiled-in list specifying +the order in which local connections should be attempted. This list +can be overridden by the +.I XLOCAL +environment variable described below. If the display name indicates a +best-choice connection should be made (e.g. +.BR :0.0 ), +each connection mechanism is tried until a connection succeeds or no +more mechanisms are available. Note: for these OSs, the Unix Domain +socket connection is treated differently from the other local connection +types. To use it the connection must be made to +.BR unix:0.0 . +.PP +The +.I XLOCAL +environment variable should contain a list of one more +more of the following: +.PP +.RS 8 +.nf +NAMED +PTS +SCO +ISC +.fi +.RE +.PP +which represent SVR4 Named Streams pipe, Old-style USL Streams pipe, +SCO XSight Streams pipe, and ISC Streams pipe, respectively. You can +select a single mechanism (e.g. +.IR XLOCAL=NAMED ), +or an ordered list (e.g. \fIXLOCAL="NAMED:PTS:SCO"\fP). +his variable overrides the compiled-in defaults. For SVR4 it is +recommended that +.I NAMED +be the first preference connection. The default setting is +.IR PTS:NAMED:ISC:SCO . +.PP +To globally override the compiled-in defaults, you should define (and +export if using +.B sh +or +.BR ksh ) +.I XLOCAL +globally. If you use startx(1) or xinit(1), the definition should be +at the top of your +.I .xinitrc +file. If you use xdm(1), the definitions should be early on in the +.I __projectroot__/lib/X11/xdm/Xsession +script. +.SH OPTIONS +.B __xservername__ +supports several mechanisms for supplying/obtaining configuration and +run-time parameters: command line options, environment variables, the +__xconfigfile__(__filemansuffix__) configuration files, auto-detection, and +fallback defaults. When the same information is supplied in more than +one way, the highest precedence mechanism is used. The list of mechanisms +is ordered from highest precedence to lowest. Note that not all parameters +can be supplied via all methods. The available command line options +and environment variables (and some defaults) are described here and in +the Xserver(__appmansuffix__) manual page. Most configuration file +parameters, with their defaults, are described in the +__xconfigfile__(__filemansuffix__) manual page. Driver and module specific +configuration parameters are described in the relevant driver or module +manual page. +.PP +In addition to the normal server options described in the +Xserver(__appmansuffix__) manual page, +.B __xservername__ +accepts the following command line switches: +.TP 8 +.BI vt XX +.I XX +specifies the Virtual Terminal device number which +.B __xservername__ +will use. Without this option, +.B __xservername__ +will pick the first available Virtual Terminal that it can locate. This +option applies only to platforms that have virtual terminal support, such +as Linux, BSD, OpenSolaris, SVR3, and SVR4. +.TP +.B \-allowMouseOpenFail +Allow the server to start up even if the mouse device can't be opened +or initialised. This is equivalent to the +.B AllowMouseOpenFail +__xconfigfile__(__filemansuffix__) file option. +.TP 8 +.B \-allowNonLocalXvidtune +Make the VidMode extension available to remote clients. This allows +the xvidtune client to connect from another host. This is equivalent +to the +.B AllowNonLocalXvidtune +__xconfigfile__(__filemansuffix__) file option. By default non-local +connections are not allowed. +.TP 8 +.BI \-bgamma " value" +Set the blue gamma correction. +.I value +must be between 0.1 and 10. +The default is 1.0. Not all drivers support this. See also the +.BR \-gamma , +.BR \-rgamma , +and +.B \-ggamma +options. +.TP 8 +.BI \-bpp " n" +No longer supported. Use +.B \-depth +to set the color depth, and use +.B \-fbbpp +if you really need to force a non-default framebuffer (hardware) pixel +format. +.TP 8 +.BI \-config " file" +Read the server configuration from +.IR file . +This option will work for any file when the server is run as root (i.e, +with real-uid 0), or for files relative to a directory in the config +search path for all other users. +.TP 8 +.BI \-configdir " directory" +Read the server configuration files from +.IR directory . +This option will work for any directory when the server is run as root +(i.e, with real-uid 0), or for directories relative to a directory in the +config directory search path for all other users. +.TP 8 +.B \-configure +When this option is specified, the +.B __xservername__ +server loads all video driver modules, probes for available hardware, +and writes out an initial __xconfigfile__(__filemansuffix__) file based on +what was detected. This option currently has some problems on some +platforms, but in most cases it is a good way to bootstrap the +configuration process. This option is only available when the server +is run as root (i.e, with real-uid 0). +.TP 8 +.BI "\-crt /dev/tty" XX +SCO only. This is the same as the +.B vt +option, and is provided for compatibility with the native SCO X server. +.TP 8 +.BI \-depth " n" +Sets the default color depth. Legal values are 1, 4, 8, 15, 16, and +24. Not all drivers support all values. +.TP 8 +.B \-disableVidMode +Disable the parts of the VidMode extension (used by the xvidtune +client) that can be used to change the video modes. This is equivalent +to the +.B DisableVidModeExtension +__xconfigfile__(__filemansuffix__) file option. +.TP 8 +.B \-fbbpp \fIn\fP +Sets the number of framebuffer bits per pixel. You should only set this +if you're sure it's necessary; normally the server can deduce the correct +value from +.B \-depth +above. Useful if you want to run a depth 24 configuration with a 24 +bpp framebuffer rather than the (possibly default) 32 bpp framebuffer +(or vice versa). Legal values are 1, 8, 16, 24, 32. Not all drivers +support all values. +.TP 8 +.B \-flipPixels +Swap the default values for the black and white pixels. +.TP 8 +.BI \-gamma " value" +Set the gamma correction. +.I value +must be between 0.1 and 10. The default is 1.0. This value is applied +equally to the R, G and B values. Those values can be set independently +with the +.BR \-rgamma , +.BR \-bgamma , +and +.B \-ggamma +options. Not all drivers support this. +.TP 8 +.BI \-ggamma " value" +Set the green gamma correction. +.I value +must be between 0.1 and 10. The default is 1.0. Not all drivers support +this. See also the +.BR \-gamma , +.BR \-rgamma , +and +.B \-bgamma +options. +.TP 8 +.B \-ignoreABI +The +.B __xservername__ +server checks the ABI revision levels of each module that it loads. It +will normally refuse to load modules with ABI revisions that are newer +than the server's. This is because such modules might use interfaces +that the server does not have. When this option is specified, mismatches +like this are downgraded from fatal errors to warnings. This option +should be used with care. +.TP 8 +.B \-isolateDevice \fIbus\-id\fP +Restrict device resets to the device at +.IR bus\-id . +The +.I bus\-id +string has the form +.IB bustype : bus : device : function +(e.g., \(oqPCI:1:0:0\(cq). +At present, only isolation of PCI devices is supported; i.e., this option +is ignored if +.I bustype +is anything other than \(oqPCI\(cq. +.TP 8 +.B \-keeptty +Prevent the server from detaching its initial controlling terminal. +This option is only useful when debugging the server. Not all platforms +support (or can use) this option. +.TP 8 +.BI \-keyboard " keyboard-name" +Use the __xconfigfile__(__filemansuffix__) file +.B InputDevice +section called +.I keyboard-name +as the core keyboard. This option is ignored when the +.B Layout +section specifies a core keyboard. In the absence of both a Layout +section and this option, the first relevant +.B InputDevice +section is used for the core keyboard. +.TP 8 +.BI \-layout " layout-name" +Use the __xconfigfile__(__filemansuffix__) file +.B Layout +section called +.IR layout-name . +By default the first +.B Layout +section is used. +.TP 8 +.BI \-logfile " filename" +Use the file called +.I filename +as the +.B __xservername__ +server log file. The default log file is +.BI __logdir__/__xservername__. n .log +on most platforms, where +.I n +is the display number of the +.B __xservername__ +server. The default may be in a different directory on some platforms. +This option is only available when the server is run as root (i.e, with +real-uid 0). +.TP 8 +.BR \-logverbose " [\fIn\fP]" +Sets the verbosity level for information printed to the +.B __xservername__ +server log file. If the +.I n +value isn't supplied, each occurrence of this option increments the log +file verbosity level. When the +.I n +value is supplied, the log file verbosity level is set to that value. +The default log file verbosity level is 3. +.TP 8 +.BI \-modulepath " searchpath" +Set the module search path to +.IR searchpath . +.I searchpath +is a comma separated list of directories to search for +.B __xservername__ +server modules. This option is only available when the server is run +as root (i.e, with real-uid 0). +.TP 8 +.B \-nosilk +Disable Silken Mouse support. +.TP 8 +.B \-pixmap24 +Set the internal pixmap format for depth 24 pixmaps to 24 bits per pixel. +The default is usually 32 bits per pixel. There is normally little +reason to use this option. Some client applications don't like this +pixmap format, even though it is a perfectly legal format. This is +equivalent to the +.B Pixmap +__xconfigfile__(__filemansuffix__) file option. +.TP 8 +.B \-pixmap32 +Set the internal pixmap format for depth 24 pixmaps to 32 bits per pixel. +This is usually the default. This is equivalent to the +.B Pixmap +__xconfigfile__(__filemansuffix__) file option. +.TP 8 +.BI \-pointer " pointer-name" +Use the __xconfigfile__(__filemansuffix__) file +.B InputDevice +section called +.I pointer-name +as the core pointer. This option is ignored when the +.B Layout +section specifies a core pointer. In the absence of both a Layout +section and this option, the first relevant +.B InputDevice +section is used for the core pointer. +.TP 8 +.B \-quiet +Suppress most informational messages at startup. The verbosity level +is set to zero. +.TP 8 +.BI \-rgamma " value" +Set the red gamma correction. +.I value +must be between 0.1 and 10. The default is 1.0. Not all drivers support +this. See also the +.BR \-gamma , +.BR \-bgamma , +and +.B \-ggamma +options. +.TP 8 +.BI \-screen " screen-name" +Use the __xconfigfile__(__filemansuffix__) file +.B Screen +section called +.IR screen-name . +By default the screens referenced by the default +.B Layout +section are used, or the first +.B Screen +section when there are no +.B Layout +sections. +.TP 8 +.B \-showconfig +This is the same as the +.B \-version +option, and is included for compatibility reasons. It may be removed +in a future release, so the +.B \-version +option should be used instead. +.TP 8 +.B \-showDefaultModulePath +Print out the default module path the server was compiled with. +.TP 8 +.B \-showDefaultLibPath +Print out the path libraries should be installed to. +.TP 8 +.B \-showopts +For each driver module installed, print out the list of options and their +argument types. +.TP 8 +.BI \-weight " nnn" +Set RGB weighting at 16 bpp. The default is 565. This applies only to +those drivers which support 16 bpp. +.TP 8 +.BR \-verbose " [\fIn\fP]" +Sets the verbosity level for information printed on stderr. If the +.I n +value isn't supplied, each occurrence of this option increments the +verbosity level. When the +.I n +value is supplied, the verbosity level is set to that value. The default +verbosity level is 0. +.TP 8 +.B \-version +Print out the server version, patchlevel, release date, the operating +system/platform it was built on, and whether it includes module loader +support. +.SH "KEYBOARD" +.PP +The +.B __xservername__ +server is normally configured to recognize various special combinations +of key presses that instruct the server to perform some action, rather +than just sending the key press event to a client application. These actions +depend on the XKB keymap loaded by a particular keyboard device and may or +may not be available on a given configuration. +.PP +The following key combinations are commonly part of the default XKEYBOARD +keymap. +.TP 8 +.B Ctrl+Alt+Backspace +Immediately kills the server -- no questions asked. It can be disabled by +setting the +.B DontZap +__xconfigfile__(__filemansuffix__) file option to a TRUE value. +.PP +.RS 8 +It should be noted that zapping is triggered by the +.B Terminate_Server +action in the keyboard map. This action is not part of the default keymaps +but can be enabled with the XKB option +.B \*qterminate:ctrl_alt_bksp\*q. +.RE +.TP 8 +.B Ctrl+Alt+Keypad-Plus +Change video mode to next one specified in the configuration file. +This can be disabled with the +.B DontZoom +__xconfigfile__(__filemansuffix__) file option. +.TP 8 +.B Ctrl+Alt+Keypad-Minus +Change video mode to previous one specified in the configuration file. +This can be disabled with the +.B DontZoom +__xconfigfile__(__filemansuffix__) file option. +.TP 8 +.B Ctrl+Alt+F1...F12 +For systems with virtual terminal support, these keystroke +combinations are used to switch to virtual terminals 1 through 12, +respectively. This can be disabled with the +.B DontVTSwitch +__xconfigfile__(__filemansuffix__) file option. +.SH CONFIGURATION +.B __xservername__ +typically uses a configuration file called +.B __xconfigfile__ +and configuration files with the suffix +.I .conf +in a directory called +.B __xconfigdir__ +for its initial setup. +Refer to the __xconfigfile__(__filemansuffix__) manual page for information +about the format of this file. +.PP +.B __xservername__ +has a mechanism for automatically generating a built-in configuration +at run-time when no +.B __xconfigfile__ +file or +.B __xconfigdir__ +files are present. The current version of this automatic configuration +mechanism works in two ways. +.PP +The first is via enhancements that have made many components of the +.B __xconfigfile__ +file optional. This means that information that can be probed or +reasonably deduced doesn't need to be specified explicitly, greatly +reducing the amount of built-in configuration information that needs to +be generated at run-time. +.PP +The second is to have "safe" fallbacks for most configuration information. +This maximises the likelihood that the +.B __xservername__ +server will start up in some usable configuration even when information +about the specific hardware is not available. +.PP +The automatic configuration support for __xservername__ is work in progress. +It is currently aimed at the most popular hardware and software platforms +supported by __xservername__. Enhancements are planned for future releases. +.SH FILES +The +.B __xservername__ +server config files can be found in a range of locations. These are +documented fully in the __xconfigfile__(__filemansuffix__) manual page. The +most commonly used locations are shown here. +.TP 30 +.B /etc/X11/__xconfigfile__ +Server configuration file. +.TP 30 +.B /etc/X11/__xconfigfile__-4 +Server configuration file. +.TP 30 +.B /etc/__xconfigfile__ +Server configuration file. +.TP 30 +.B __projectroot__/etc/__xconfigfile__ +Server configuration file. +.TP 30 +.B __projectroot__/lib/X11/__xconfigfile__ +Server configuration file. +.TP 30 +.B /etc/X11/__xconfigdir__ +Server configuration directory. +.TP 30 +.B /etc/X11/__xconfigdir__-4 +Server configuration directory. +.TP 30 +.B /etc/__xconfigdir__ +Server configuration directory. +.TP 30 +.B __projectroot__/etc/__xconfigdir__ +Server configuration directory. +.TP 30 +.B __projectroot__/lib/X11/__xconfigdir__ +Server configuration directory. +.TP 30 +.BI __logdir__/__xservername__. n .log +Server log file for display +.IR n . +.TP 30 +.B __projectroot__/bin/\(** +Client binaries. +.TP 30 +.B __projectroot__/include/\(** +Header files. +.TP 30 +.B __projectroot__/lib/\(** +Libraries. +.TP 30 +.B __datadir__/fonts/X11/\(** +Fonts. +.TP 30 +.B __projectroot__/share/X11/XErrorDB +Client error message database. +.TP 30 +.B __projectroot__/lib/X11/app-defaults/\(** +Client resource specifications. +.TP 30 +.B __mandir__/man?/\(** +Manual pages. +.TP 30 +.BI /etc/X n .hosts +Initial access control list for display +.IR n . +.SH "SEE ALSO" +X(__miscmansuffix__), Xserver(__appmansuffix__), xdm(__appmansuffix__), xinit(__appmansuffix__), +__xconfigfile__(__filemansuffix__), xvidtune(__appmansuffix__), +apm(__drivermansuffix__), +ati(__drivermansuffix__), +chips(__drivermansuffix__), +cirrus(__drivermansuffix__), +cyrix(__drivermansuffix__), +fbdev(__drivermansuffix__), +glide(__drivermansuffix__), +glint(__drivermansuffix__), +i128(__drivermansuffix__), +i740(__drivermansuffix__), +imstt(__drivermansuffix__), +intel(__drivermansuffix__), +mga(__drivermansuffix__), +neomagic(__drivermansuffix__), +nsc(__drivermansuffix__), +nv(__drivermansuffix__), +openchrome (__drivermansuffix__), +r128(__drivermansuffix__), +rendition(__drivermansuffix__), +s3virge(__drivermansuffix__), +siliconmotion(__drivermansuffix__), +sis(__drivermansuffix__), +sunbw2(__drivermansuffix__), +suncg14(__drivermansuffix__), +suncg3(__drivermansuffix__), +suncg6(__drivermansuffix__), +sunffb(__drivermansuffix__), +sunleo(__drivermansuffix__), +suntcx(__drivermansuffix__), +tdfx(__drivermansuffix__), +tga(__drivermansuffix__), +trident(__drivermansuffix__), +tseng(__drivermansuffix__), +v4l(__drivermansuffix__), +vesa(__drivermansuffix__), +vmware(__drivermansuffix__), +.br +Web site +.IR <http://www.x.org> . + +.SH AUTHORS +__xservername__ has many contributors world wide. The names of most of them +can be found in the documentation, ChangeLog files in the source tree, +and in the actual source code. +.PP +__xservername__ was originally based on XFree86 4.4rc2. +That was originally based on \fIX386 1.2\fP by Thomas Roell, which +was contributed to the then X Consortium's X11R5 distribution by SGCS. +.PP +__xservername__ is released by the X.Org Foundation. +.PP +The project that became XFree86 was originally founded in 1992 by +David Dawes, Glenn Lai, Jim Tsillas and David Wexelblat. +.PP +XFree86 was later integrated in the then X Consortium's X11R6 release +by a group of dedicated XFree86 developers, including the following: +.PP +.RS 4 +.nf +Stuart Anderson \fIanderson@metrolink.com\fP +Doug Anson \fIdanson@lgc.com\fP +Gertjan Akkerman \fIakkerman@dutiba.twi.tudelft.nl\fP +Mike Bernson \fImike@mbsun.mlb.org\fP +Robin Cutshaw \fIrobin@XFree86.org\fP +David Dawes \fIdawes@XFree86.org\fP +Marc Evans \fImarc@XFree86.org\fP +Pascal Haible \fIhaible@izfm.uni-stuttgart.de\fP +Matthieu Herrb \fIMatthieu.Herrb@laas.fr\fP +Dirk Hohndel \fIhohndel@XFree86.org\fP +David Holland \fIdavidh@use.com\fP +Alan Hourihane \fIalanh@fairlite.demon.co.uk\fP +Jeffrey Hsu \fIhsu@soda.berkeley.edu\fP +Glenn Lai \fIglenn@cs.utexas.edu\fP +Ted Lemon \fImellon@ncd.com\fP +Rich Murphey \fIrich@XFree86.org\fP +Hans Nasten \fInasten@everyware.se\fP +Mark Snitily \fImark@sgcs.com\fP +Randy Terbush \fIrandyt@cse.unl.edu\fP +Jon Tombs \fItombs@XFree86.org\fP +Kees Verstoep \fIversto@cs.vu.nl\fP +Paul Vixie \fIpaul@vix.com\fP +Mark Weaver \fIMark_Weaver@brown.edu\fP +David Wexelblat \fIdwex@XFree86.org\fP +Philip Wheatley \fIPhilip.Wheatley@ColumbiaSC.NCR.COM\fP +Thomas Wolfram \fIwolf@prz.tu-berlin.de\fP +Orest Zborowski \fIorestz@eskimo.com\fP +.fi +.RE +.PP +__xservername__ source is available from the FTP server +\fI<ftp://ftp.x.org/>\fP, and from the X.Org +server \fI<http://gitweb.freedesktop.org/>\fP. Documentation and other +information can be found from the X.Org web site +\fI<http://www.x.org/>\fP. + +.SH LEGAL +.PP +.B __xservername__ +is copyright software, provided under licenses that permit modification +and redistribution in source and binary form without fee. +.B __xservername__ is copyright by numerous authors and +contributors from around the world. Licensing information can be found +at +.IR <http://www.x.org> . +Refer to the source code for specific copyright notices. +.PP +.B XFree86(TM) +is a trademark of The XFree86 Project, Inc. +.PP +.B X11(TM) +and +.B X Window System(TM) +are trademarks of The Open Group. diff --git a/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre b/xorg-server/hw/xfree86/doc/man/xorg.conf.man index 2267a0a1a..e3fd0eadf 100644 --- a/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre +++ b/xorg-server/hw/xfree86/doc/man/xorg.conf.man @@ -1,2478 +1,2478 @@ -.\" shorthand for double quote that works everywhere.
-.ds q \N'34'
-.TH __xconfigfile__ __filemansuffix__ __vendorversion__
-.SH NAME
-__xconfigfile__ and __xconfigdir__ \- configuration files for
-__xservername__ X server
-.SH INTRODUCTION
-.B __xservername__
-supports several mechanisms for supplying/obtaining configuration and
-run-time parameters: command line options, environment variables, the
-__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
-and fallback defaults. When the same information is supplied in more
-than one way, the highest precedence mechanism is used. The list of
-mechanisms is ordered from highest precedence to lowest. Note that not
-all parameters can be supplied via all methods. The available command
-line options and environment variables (and some defaults) are
-described in the Xserver(__appmansuffix__) and
-__xservername__(__appmansuffix__) manual pages. Most configuration file
-parameters, with their defaults, are described below. Driver and module
-specific configuration parameters are described in the relevant driver
-or module manual page.
-.SH DESCRIPTION
-.B __xservername__
-uses a configuration file called
-.I __xconfigfile__
-and files ending in the suffix
-.I .conf
-from the directory
-.I __xconfigdir__
-for its initial setup.
-The
-.I __xconfigfile__
-configuration file is searched for in the following places when the
-server is started as a normal user:
-.PP
-.RS 4
-.nf
-.IR /etc/X11/ <cmdline>
-.IR __projectroot__/etc/X11/ <cmdline>
-.IB /etc/X11/ $XORGCONFIG
-.IB __projectroot__/etc/X11/ $XORGCONFIG
-.I /etc/X11/__xconfigfile__
-.I /etc/__xconfigfile__
-.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
-.I __projectroot__/etc/X11/__xconfigfile__
-.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
-.I __projectroot__/lib/X11/__xconfigfile__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is a relative path (with no \(lq..\(rq components) specified with the
-.B \-config
-command line option,
-.B $XORGCONFIG
-is the relative path (with no \(lq..\(rq components) specified by that
-environment variable, and
-.I <hostname>
-is the machine's hostname as reported by
-.BR gethostname (__libmansuffix__).
-.PP
-When the __xservername__ server is started by the \(lqroot\(rq user, the config file
-search locations are as follows:
-.PP
-.RS 4
-.nf
-<cmdline>
-.IR /etc/X11/ <cmdline>
-.IR __projectroot__/etc/X11/ <cmdline>
-.B $XORGCONFIG
-.IB /etc/X11/ $XORGCONFIG
-.IB __projectroot__/etc/X11/ $XORGCONFIG
-.I /etc/X11/__xconfigfile__
-.I /etc/__xconfigfile__
-.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
-.I __projectroot__/etc/X11/__xconfigfile__
-.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
-.I __projectroot__/lib/X11/__xconfigfile__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is the path specified with the
-.B \-config
-command line option (which may be absolute or relative),
-.B $XORGCONFIG
-is the path specified by that
-environment variable (absolute or relative),
-.B $HOME
-is the path specified by that environment variable (usually the home
-directory), and
-.I <hostname>
-is the machine's hostname as reported by
-.BR gethostname (__libmansuffix__).
-.PP
-Additional configuration files are searched for in the following
-directories when the server is started as a normal user:
-.PP
-.RS 4
-.nf
-.IR /etc/X11/ <cmdline>
-.IR __sysconfdir__/X11/ <cmdline>
-.I /etc/X11/__xconfigdir__
-.I __sysconfdir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is a relative path (with no \(lq..\(rq components) specified with the
-.B \-configdir
-command line option.
-.PP
-When the __xservername__ server is started by the \(lqroot\(rq user, the
-config directory search locations are as follows:
-.PP
-.RS 4
-.nf
-<cmdline>
-.IR /etc/X11/ <cmdline>
-.IR __sysconfdir__/X11/ <cmdline>
-.I /etc/X11/__xconfigdir__
-.I __sysconfdir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is the path specified with the
-.B \-configdir
-command line option (which may be absolute or relative).
-.PP
-Finally, configuration files will also be searched for in directories
-reserved for system use. These are to separate configuration files from
-the vendor or 3rd party packages from those of local administration.
-These files are found in the following directories:
-.PP
-.RS 4
-.nf
-.I /usr/share/X11/__xconfigdir__
-.I __datadir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-The
-.I __xconfigfile__
-and
-.I __xconfigdir__
-files are composed of a number of sections which may be present in any order,
-or omitted to use default configuration values.
-Each section has the form:
-.PP
-.RS 4
-.nf
-.BI "Section \*q" SectionName \*q
-.RI " " SectionEntry
- ...
-.B EndSection
-.fi
-.RE
-.PP
-The section names are:
-.PP
-.RS 4
-.nf
-.BR "Files " "File pathnames"
-.BR "ServerFlags " "Server flags"
-.BR "Module " "Dynamic module loading"
-.BR "Extensions " "Extension enabling"
-.BR "InputDevice " "Input device description"
-.BR "InputClass " "Input class description"
-.BR "Device " "Graphics device description"
-.BR "VideoAdaptor " "Xv video adaptor description"
-.BR "Monitor " "Monitor description"
-.BR "Modes " "Video modes descriptions"
-.BR "Screen " "Screen configuration"
-.BR "ServerLayout " "Overall layout"
-.BR "DRI " "DRI\-specific configuration"
-.BR "Vendor " "Vendor\-specific configuration"
-.fi
-.RE
-.PP
-The following obsolete section names are still recognised for compatibility
-purposes.
-In new config files, the
-.B InputDevice
-section should be used instead.
-.PP
-.RS 4
-.nf
-.BR "Keyboard " "Keyboard configuration"
-.BR "Pointer " "Pointer/mouse configuration"
-.fi
-.RE
-.PP
-The old
-.B XInput
-section is no longer recognised.
-.PP
-The
-.B ServerLayout
-sections are at the highest level.
-They bind together the input and output devices that will be used in a session.
-The input devices are described in the
-.B InputDevice
-sections.
-Output devices usually consist of multiple independent components (e.g.,
-a graphics board and a monitor).
-These multiple components are bound together in the
-.B Screen
-sections, and it is these that are referenced by the
-.B ServerLayout
-section.
-Each
-.B Screen
-section binds together a graphics board and a monitor.
-The graphics boards are described in the
-.B Device
-sections, and the monitors are described in the
-.B Monitor
-sections.
-.PP
-Config file keywords are case\-insensitive, and \(lq_\(rq characters are
-ignored.
-Most strings (including
-.B Option
-names) are also case-insensitive, and insensitive to white space and
-\(lq_\(rq characters.
-.PP
-Each config file entry usually takes up a single line in the file. They
-consist of a keyword, which is possibly followed by one or more arguments,
-with the number and types of the arguments depending on the keyword.
-The argument types are:
-.PP
-.RS 4
-.nf
-.BR "Integer " "an integer number in decimal, hex or octal"
-.BR "Real " "a floating point number"
-.BR "String " "a string enclosed in double quote marks (\*q)"
-.fi
-.RE
-.PP
-Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values
-with \(lq0\(rq.
-.PP
-A special keyword called
-.B Option
-may be used to provide free\-form data to various components of the server.
-The
-.B Option
-keyword takes either one or two string arguments.
-The first is the option name, and the optional second argument is the
-option value.
-Some commonly used option value types include:
-.PP
-.RS 4
-.nf
-.BR "Integer " "an integer number in decimal, hex or octal"
-.BR "Real " "a floating point number"
-.BR "String " "a sequence of characters"
-.BR "Boolean " "a boolean value (see below)"
-.BR "Frequency " "a frequency value (see below)"
-.fi
-.RE
-.PP
-Note that
-.I all
-.B Option
-values, not just strings, must be enclosed in quotes.
-.PP
-Boolean options may optionally have a value specified.
-When no value is specified, the option's value is
-.BR TRUE .
-The following boolean option values are recognised as
-.BR TRUE :
-.PP
-.RS 4
-.BR 1 ,
-.BR on ,
-.BR true ,
-.B yes
-.RE
-.PP
-and the following boolean option values are recognised as
-.BR FALSE :
-.PP
-.RS 4
-.BR 0 ,
-.BR off ,
-.BR false ,
-.B no
-.RE
-.PP
-If an option name is prefixed with
-.RB \*q No \*q,
-then the option value is negated.
-.PP
-Example: the following option entries are equivalent:
-.PP
-.RS 4
-.nf
-.B "Option \*qAccel\*q \*qOff\*q"
-.B "Option \*qNoAccel\*q"
-.B "Option \*qNoAccel\*q \*qOn\*q"
-.B "Option \*qAccel\*q \*qfalse\*q"
-.B "Option \*qAccel\*q \*qno\*q"
-.fi
-.RE
-.PP
-Frequency option values consist of a real number that is optionally
-followed by one of the following frequency units:
-.PP
-.RS 4
-.BR Hz ,
-.BR k ,
-.BR kHz ,
-.BR M ,
-.B MHz
-.RE
-.PP
-When the unit name is omitted, the correct units will be determined from
-the value and the expectations of the appropriate range of the value.
-It is recommended that the units always be specified when using frequency
-option values to avoid any errors in determining the value.
-.SH "FILES SECTION"
-The
-.B Files
-section is used to specify some path names required by the server.
-Some of these paths can also be set from the command line (see
-.BR Xserver (__appmansuffix__)
-and
-.BR __xservername__ (__appmansuffix__)).
-The command line settings override the values specified in the config
-file.
-The
-.B Files
-section is optional, as are all of the entries that may appear in it.
-.PP
-The entries that can appear in this section are:
-.TP 7
-.BI "FontPath \*q" path \*q
-sets the search path for fonts.
-This path is a comma separated list of font path elements which the __xservername__
-server searches for font databases.
-Multiple
-.B FontPath
-entries may be specified, and they will be concatenated to build up the
-fontpath used by the server. Font path elements can be absolute
-directory paths, catalogue directories or a font server identifier. The
-formats of the later two are explained below:
-.PP
-.RS 7
-Catalogue directories:
-.PP
-.RS 4
-Catalogue directories can be specified using the prefix \fBcatalogue:\fR
-before the directory name. The directory can then be populated with
-symlinks pointing to the real font directories, using the following
-syntax in the symlink name:
-.PP
-.RS 4
-.IR <identifier> : [attribute]: pri= <priority>
-.RE
-.PP
-where
-.I <identifier>
-is an alphanumeric identifier,
-.I [attribute]
-is an attribute which will be passed to the underlying FPE and
-.I <priority>
-is a number used to order the fontfile FPEs. Examples:
-.PP
-.RS 4
-.nf
-.I 75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi
-.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript
-.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
-.fi
-.PP
-.RE .RE .RE
-.PP
-.RS 7
-Font server identifiers:
-.PP
-.RS 4
-Font server identifiers have the form:
-.RS 4
-.PP
-.IR <trans> / <hostname> : <port\-number>
-.RE
-.PP
-where
-.I <trans>
-is the transport type to use to connect to the font server (e.g.,
-.B unix
-for UNIX\-domain sockets or
-.B tcp
-for a TCP/IP connection),
-.I <hostname>
-is the hostname of the machine running the font server, and
-.I <port\-number>
-is the port number that the font server is listening on (usually 7100).
-.RE
-.PP
-When this entry is not specified in the config file, the server falls back
-to the compiled\-in default font path, which contains the following
-font path elements (which can be set inside a catalogue directory):
-.PP
-.RS 4
-.nf
-.I __datadir__/fonts/X11/misc/
-.I __datadir__/fonts/X11/TTF/
-.I __datadir__/fonts/X11/OTF/
-.I __datadir__/fonts/X11/Type1/
-.I __datadir__/fonts/X11/100dpi/
-.I __datadir__/fonts/X11/75dpi/
-.fi
-.RE
-.PP
-Font path elements that are found to be invalid are removed from the
-font path when the server starts up.
-.RE
-.TP 7
-.BI "ModulePath \*q" path \*q
-sets the search path for loadable __xservername__ server modules.
-This path is a comma separated list of directories which the __xservername__ server
-searches for loadable modules loading in the order specified.
-Multiple
-.B ModulePath
-entries may be specified, and they will be concatenated to build the
-module search path used by the server. The default module path is
-.PP
-.RS 11
-__modulepath__
-.RE
-.\" The LogFile keyword is not currently implemented
-.ig
-.TP 7
-.BI "LogFile \*q" path \*q
-sets the name of the __xservername__ server log file.
-The default log file name is
-.PP
-.RS 11
-.RI __logdir__/__xservername__. <n> .log
-.RE
-.PP
-.RS 7
-where
-.I <n>
-is the display number for the __xservername__ server.
-..
-.TP 7
-.BI "XkbDir \*q" path \*q
-sets the base directory for keyboard layout files. The
-.B \-xkbdir
-command line option can be used to override this. The default directory is
-.PP
-.RS 11
-__xkbdir__
-.RE
-.SH "SERVERFLAGS SECTION"
-In addition to options specific to this section (described below), the
-.B ServerFlags
-section is used to specify some global
-__xservername__ server options.
-All of the entries in this section are
-.BR Options ,
-although for compatibility purposes some of the old style entries are
-still recognised.
-Those old style entries are not documented here, and using them is
-discouraged.
-The
-.B ServerFlags
-section is optional, as are the entries that may be specified in it.
-.PP
-.B Options
-specified in this section (with the exception of the
-.B \*qDefaultServerLayout\*q
-.BR Option )
-may be overridden by
-.B Options
-specified in the active
-.B ServerLayout
-section.
-Options with command line equivalents are overridden when their command
-line equivalent is used.
-The options recognised by this section are:
-.TP 7
-.BI "Option \*qDefaultServerLayout\*q \*q" layout\-id \*q
-This specifies the default
-.B ServerLayout
-section to use in the absence of the
-.B \-layout
-command line option.
-.TP 7
-.BI "Option \*qNoTrapSignals\*q \*q" boolean \*q
-This prevents the __xservername__ server from trapping a range of unexpected fatal
-signals and exiting cleanly.
-Instead, the __xservername__ server will die and drop core where the fault occurred.
-The default behaviour is for the __xservername__ server to exit cleanly, but still drop a
-core file.
-In general you never want to use this option unless you are debugging an __xservername__
-server problem and know how to deal with the consequences.
-.TP 7
-.BI "Option \*qUseSIGIO\*q \*q" boolean \*q
-This controls whether the __xservername__ server requests that events from
-input devices be reported via a SIGIO signal handler (also known as SIGPOLL
-on some platforms), or only reported via the standard select(3) loop.
-The default behaviour is platform specific. In general you do not want to
-use this option unless you are debugging the __xservername__ server, or
-working around a specific bug until it is fixed, and understand the
-consequences.
-.TP 7
-.BI "Option \*qDontVTSwitch\*q \*q" boolean \*q
-This disallows the use of the
-.BI Ctrl+Alt+F n
-sequence (where
-.RI F n
-refers to one of the numbered function keys).
-That sequence is normally used to switch to another \*qvirtual terminal\*q
-on operating systems that have this feature.
-When this option is enabled, that key sequence has no special meaning and
-is passed to clients.
-Default: off.
-.TP 7
-.BI "Option \*qDontZap\*q \*q" boolean \*q
-This disallows the use of the
-.B Terminate_Server
-XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options).
-This action is normally used to terminate the __xservername__ server.
-When this option is enabled, the action has no effect.
-Default: off.
-.TP 7
-.BI "Option \*qDontZoom\*q \*q" boolean \*q
-This disallows the use of the
-.B Ctrl+Alt+Keypad\-Plus
-and
-.B Ctrl+Alt+Keypad\-Minus
-sequences.
-These sequences allows you to switch between video modes.
-When this option is enabled, those key sequences have no special meaning
-and are passed to clients.
-Default: off.
-.TP 7
-.BI "Option \*qDisableVidModeExtension\*q \*q" boolean \*q
-This disables the parts of the VidMode extension used by the xvidtune client
-that can be used to change the video modes.
-Default: the VidMode extension is enabled.
-.TP 7
-.BI "Option \*qAllowNonLocalXvidtune\*q \*q" boolean \*q
-This allows the xvidtune client (and other clients that use the VidMode
-extension) to connect from another host.
-Default: off.
-.TP 7
-.BI "Option \*qAllowMouseOpenFail\*q \*q" boolean \*q
-This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__)
-drivers to not report failure if the mouse device can't be opened/initialised.
-It has no effect on the evdev(__drivermansuffix__) or other drivers.
-Default: false.
-.TP 7
-.BI "Option \*qVTSysReq\*q \*q" boolean \*q
-enables the SYSV\-style VT switch sequence for non\-SYSV systems
-which support VT switching.
-This sequence is
-.B Alt\-SysRq
-followed by a function key
-.RB ( Fn ).
-This prevents the __xservername__ server trapping the
-keys used for the default VT switch sequence, which means that clients can
-access them.
-Default: off.
-.TP 7
-.BI "Option \*qBlankTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B blank
-phase of the screensaver.
-.I time
-is in minutes.
-This is equivalent to the __xservername__ server's
-.B \-s
-flag, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-.TP 7
-.BI "Option \*qStandbyTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B standby
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qSuspendTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B suspend
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qOffTime\*q \*q" time \*q
-sets the inactivity timeout for the
-.B off
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qPixmap\*q \*q" bpp \*q
-This sets the pixmap format to use for depth 24.
-Allowed values for
-.I bpp
-are 24 and 32.
-Default: 32 unless driver constraints don't allow this (which is rare).
-Note: some clients don't behave well when this value is set to 24.
-.TP 7
-.BI "Option \*qPC98\*q \*q" boolean \*q
-Specify that the machine is a Japanese PC\-98 machine.
-This should not be enabled for anything other than the Japanese\-specific
-PC\-98 architecture.
-Default: auto\-detected.
-.TP 7
-.BI "Option \*qNoPM\*q \*q" boolean \*q
-Disables something to do with power management events.
-Default: PM enabled on platforms that support it.
-.TP 7
-.BI "Option \*qXinerama\*q \*q" boolean \*q
-enable or disable XINERAMA extension.
-Default is disabled.
-.TP 7
-.BI "Option \*qAIGLX\*q \*q" boolean \*q
-enable or disable AIGLX. AIGLX is enabled by default.
-.TP 7
-.BI "Option \*qDRI2\*q \*q" boolean \*q
-enable or disable DRI2. DRI2 is disabled by default.
-.TP 7
-.BI "Option \*qGlxVisuals\*q \*q" string \*q
-This option controls how many GLX visuals the GLX modules sets up.
-The default value is
-.BR "typical" ,
-which will setup up a typical subset of
-the GLXFBConfigs provided by the driver as GLX visuals. Other options are
-.BR "minimal" ,
-which will set up the minimal set allowed by the GLX specification and
-.BR "all"
-which will setup GLX visuals for all GLXFBConfigs.
-.TP 7
-.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
-Include the default font path even if other paths are specified in
-xorg.conf. If enabled, other font paths are included as well. Enabled by
-default.
-.TP 7
-.BI "Option \*qIgnoreABI\*q \*q" boolean \*q
-Allow modules built for a different, potentially incompatible version of
-the X server to load. Disabled by default.
-.TP 7
-.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q
-If this option is disabled, then no devices will be added from HAL events.
-Enabled by default.
-.TP 7
-.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q
-If this option is disabled, then the devices will be added (and the
-DevicePresenceNotify event sent), but not enabled, thus leaving policy up
-to the client.
-Enabled by default.
-.TP 7
-.BI "Option \*qLog\*q \*q" string \*q
-This option controls whether the log is flushed and/or synced to disk after
-each message.
-Possible values are
-.B flush
-or
-.BR sync .
-Unset by default.
-.SH "MODULE SECTION"
-The
-.B Module
-section is used to specify which __xservername__ server modules should be loaded.
-This section is ignored when the __xservername__ server is built in static form.
-The type of modules normally loaded in this section are __xservername__ server
-extension modules.
-Most other module types are loaded automatically when they are needed via
-other mechanisms.
-The
-.B Module
-section is optional, as are all of the entries that may be specified in
-it.
-.PP
-Entries in this section may be in two forms.
-The first and most commonly used form is an entry that uses the
-.B Load
-keyword, as described here:
-.TP 7
-.BI "Load \*q" modulename \*q
-This instructs the server to load the module called
-.IR modulename .
-The module name given should be the module's standard name, not the
-module file name.
-The standard name is case\-sensitive, and does not include the \(lqlib\(rq
-prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes.
-.PP
-.RS 7
-Example: the DRI extension module can be loaded with the following entry:
-.PP
-.RS 4
-.B "Load \*qdri\*q"
-.RE
-.RE
-.TP 7
-.BI "Disable \*q" modulename \*q
-This instructs the server to not load the module called
-.IR modulename .
-Some modules are loaded by default in the server, and this overrides that
-default. If a
-.B Load
-instruction is given for the same module, it overrides the
-.B Disable
-instruction and the module is loaded. The module name given should be the
-module's standard name, not the module file name. As with the
-.B Load
-instruction, the standard name is case-sensitive, and does not include the
-"lib" prefix, or the ".a", ".o", or ".so" suffixes.
-.PP
-The second form of entry is a
-.BR SubSection,
-with the subsection name being the module name, and the contents of the
-.B SubSection
-being
-.B Options
-that are passed to the module when it is loaded.
-.PP
-Example: the extmod module (which contains a miscellaneous group of
-server extensions) can be loaded, with the XFree86\-DGA extension
-disabled by using the following entry:
-.PP
-.RS 4
-.nf
-.B "SubSection \*qextmod\*q"
-.B " Option \*qomit XFree86\-DGA\*q"
-.B EndSubSection
-.fi
-.RE
-.PP
-Modules are searched for in each directory specified in the
-.B ModulePath
-search path, and in the drivers, extensions, input, internal, and
-multimedia subdirectories of each of those directories.
-In addition to this, operating system specific subdirectories of all
-the above are searched first if they exist.
-.PP
-To see what extension modules are available, check the extensions
-subdirectory under:
-.PP
-.RS 4
-.nf
-__modulepath__
-.fi
-.RE
-.PP
-The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq,
-and \(lqrecord\(rq extension modules are loaded automatically, if they
-are present, unless disabled with \*qDisable\*q entries.
-It is recommended
-that at very least the \(lqextmod\(rq extension module be loaded.
-If it isn't, some commonly used server extensions (like the SHAPE
-extension) will not be available.
-.SH "EXTENSIONS SECTION"
-The
-.B Extensions
-section is used to specify which X11 protocol extensions should be enabled
-or disabled.
-The
-.B Extensions
-section is optional, as are all of the entries that may be specified in
-it.
-.PP
-Entries in this section are listed as Option statements with the name of
-the extension as the first argument, and a boolean value as the second.
-The extension name is case\-sensitive, and matches the form shown in the output
-of \*qXorg -extension ?\*q.
-.PP
-.RS 7
-Example: the MIT-SHM extension can be disabled with the following entry:
-.PP
-.RS 4
-.nf
-.B "Section \*qExtensions\*q"
-.B " Option \*qMIT-SHM\*q \*qDisable\*q"
-.B "EndSection"
-.fi
-.RE
-.RE
-.SH "INPUTDEVICE SECTION"
-The config file may have multiple
-.B InputDevice
-sections.
-Recent X servers employ input hotplugging to add input devices, with the HAL
-backend being the default backend for X servers since 1.4. It is usually not
-necessary to provide
-.B InputDevice
-sections in the xorg.conf if hotplugging is enabled.
-.PP
-If hotplugging is disabled, there will normally
-be at least two: one for the core (primary) keyboard
-and one for the core pointer.
-If either of these two is missing, a default configuration for the missing
-ones will be used. In the absence of an explicitly specified core input
-device, the first
-.B InputDevice
-marked as
-.B CorePointer
-(or
-.BR CoreKeyboard )
-is used.
-If there is no match there, the first
-.B InputDevice
-that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used.
-The final fallback is to use built\-in default configurations.
-Currently the default configuration may not work as expected on all platforms.
-.PP
-.B InputDevice
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qInputDevice\*q"
-.BI " Identifier \*q" name \*q
-.BI " Driver \*q" inputdriver \*q
-.I " options"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Driver
-entries are required in all
-.B InputDevice
-sections.
-All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this input device.
-The
-.B Driver
-entry specifies the name of the driver to use for this input device.
-When using the loadable server, the input driver module
-.RI \*q inputdriver \*q
-will be loaded for each active
-.B InputDevice
-section.
-An
-.B InputDevice
-section is considered active if it is referenced by an active
-.B ServerLayout
-section, if it is referenced by the
-.B \-keyboard
-or
-.B \-pointer
-command line options, or if it is selected implicitly as the core pointer
-or keyboard device in the absence of such explicit references.
-The most commonly used input drivers are
-.BR evdev (__drivermansuffix__)
-on Linux systems, and
-.BR kbd (__drivermansuffix__)
-and
-.BR mousedrv (__drivermansuffix__)
-on other platforms.
-.PP
-.PP
-.B InputDevice
-sections recognise some driver\-independent
-.BR Options ,
-which are described here.
-See the individual input driver manual pages for a description of the
-device\-specific options.
-.TP 7
-.BI "Option \*qAutoServerLayout\*q \*q" boolean \*q
-Always add the device to the ServerLayout section used by this instance of
-the server. This affects implied layouts as well as explicit layouts
-specified in the configuration and/or on the command line.
-.TP 7
-.BI "Option \*qCorePointer\*q"
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qCoreKeyboard\*q"
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qAlwaysCore\*q \*q" boolean \*q
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qSendCoreEvents\*q \*q" boolean \*q
-Deprecated, see
-.B Floating
-
-.TP 7
-.BI "Option \*qFloating\*q \*q" boolean \*q
-When enabled, the input device is set up floating and does not
-report events through any master device or control a cursor. The device is
-only available to clients using the X Input Extension API. This option is
-disabled by default.
-The options
-.B CorePointer,
-.B CoreKeyboard,
-.B AlwaysCore,
-and
-.B SendCoreEvents,
-are the inverse of option
-.B Floating
-(i.e.
-.B SendCoreEvents \*qon\*q
-is equivalent to
-.B Floating \*qoff\*q
-).
-
-This option controls the startup behavior only, a device
-may be reattached or set floating at runtime.
-.PP
-For pointing devices, the following options control how the pointer
-is accelerated or decelerated with respect to physical device motion. Most of
-these can be adjusted at runtime, see the xinput(1) man page for details. Only
-the most important acceleration options are discussed here.
-.TP 7
-.BI "Option \*qAccelerationProfile\*q \*q" integer \*q
-Select the profile. In layman's terms, the profile constitutes the "feeling" of
-the acceleration. More formally, it defines how the transfer function (actual
-acceleration as a function of current device velocity and acceleration controls)
-is constructed. This is mainly a matter of personal preference.
-.PP
-.RS 6
-.nf
-.B " 0 classic (mostly compatible)"
-.B "-1 none (only constant deceleration is applied)"
-.B " 1 device-dependent"
-.B " 2 polynomial (polynomial function)"
-.B " 3 smooth linear (soft knee, then linear)"
-.B " 4 simple (normal when slow, otherwise accelerated)"
-.B " 5 power (power function)"
-.B " 6 linear (more speed, more acceleration)"
-.B " 7 limited (like linear, but maxes out at threshold)"
-.fi
-.RE
-.TP 7
-.BI "Option \*qConstantDeceleration\*q \*q" real \*q
-Makes the pointer go
-.B deceleration
-times slower than normal. Most useful for high-resolution devices.
-.TP 7
-.BI "Option \*qAdaptiveDeceleration\*q \*q" real \*q
-Allows to actually decelerate the pointer when going slow. At most, it will be
-.B adaptive deceleration
-times slower. Enables precise pointer placement without sacrificing speed.
-.TP 7
-.BI "Option \*qAccelerationScheme\*q \*q" string \*q
-Selects the scheme, which is the underlying algorithm.
-.PP
-.RS 7
-.nf
-.B "predictable default algorithm (behaving more predictable)"
-.B "lightweight old acceleration code (as specified in the X protocol spec)"
-.B "none no acceleration or deceleration"
-.fi
-.RE
-.TP 7
-.BI "Option \*qAccelerationNumerator\*q \*q" integer \*q
-.TP 7
-.BI "Option \*qAccelerationDenominator\*q \*q" integer \*q
-Set numerator and denominator of the acceleration factor. The acceleration
-factor is a rational which, together with threshold, can be used to tweak
-profiles to suit the users needs. The
-.B simple
-and
-.B limited
-profiles use it directly (i.e. they accelerate by the factor), for other
-profiles it should hold that a higher acceleration factor leads to a faster
-pointer. Typically, 1 is unaccelerated and values up to 5 are sensible.
-.TP 7
-.BI "Option \*qAccelerationThreshold\*q \*q" integer \*q
-Set the threshold, which is roughly the velocity (usually device units per 10
-ms) required for acceleration to become effective. The precise effect varies
-with the profile however.
-
-.SH "INPUTCLASS SECTION"
-The config file may have multiple
-.B InputClass
-sections.
-These sections are optional and are used to provide configuration for a
-class of input devices as they are automatically added. An input device can
-match more than one
-.B InputClass
-section. Each class can override settings from a previous class, so it is
-best to arrange the sections with the most generic matches first.
-.PP
-.B InputClass
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qInputClass\*q"
-.BI " Identifier \*q" name \*q
-.I " entries"
-.I " ..."
-.I " options"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-entry is required in all
-.B InputClass
-sections.
-All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this input class.
-The
-.B Driver
-entry specifies the name of the driver to use for this input device.
-After all classes have been examined, the
-.RI \*q inputdriver \*q
-module from the first
-.B Driver
-entry will be enabled when using the loadable server.
-.PP
-When an input device is automatically added, its characteristics are
-checked against all
-.B InputClass
-sections. Each section can contain optional entries to narrow the match
-of the class. If none of the optional entries appear, the
-.B InputClass
-section is generic and will match any input device. If more than one of
-these entries appear, they all must match for the configuration to apply.
-.PP
-There are two types of match entries used in
-.B InputClass
-sections. The first allows various tokens to be matched against attributes
-of the device. An entry can be constructed to match attributes from different
-devices by separating arguments with a '|' character. Multiple entries of the
-same type may be supplied to add multiple matching conditions on the same
-attribute. For example:
-.PP
-.RS 4
-.nf
-.B "Section \*qInputClass\*q"
-.B " Identifier \*qMy Class\*q"
-.B " # product string must contain example and
-.B " # either gizmo or gadget
-.B " MatchProduct \*qexample\*q
-.B " MatchProduct \*qgizmo|gadget\*q
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.TP 7
-.BI "MatchProduct \*q" matchproduct \*q
-This entry can be used to check if the substring
-.RI \*q matchproduct \*q
-occurs in the device's product name.
-.TP 7
-.BI "MatchVendor \*q" matchvendor \*q
-This entry can be used to check if the substring
-.RI \*q matchvendor \*q
-occurs in the device's vendor name.
-.TP 7
-.BI "MatchDevicePath \*q" matchdevice \*q
-This entry can be used to check if the device file matches the
-.RI \*q matchdevice \*q
-pathname pattern.
-.TP 7
-.BI "MatchOS \*q" matchos \*q
-This entry can be used to check if the operating system matches the
-case-insensitive
-.RI \*q matchos \*q
-string. This entry is only supported on platforms providing the
-.BR uname (2)
-system call.
-.TP 7
-.BI "MatchPnPID \*q" matchpnp \*q
-The device's Plug and Play (PnP) ID can be checked against the
-.RI \*q matchpnp \*q
-shell wildcard pattern.
-.TP 7
-.BI "MatchUSBID \*q" matchusb \*q
-The device's USB ID can be checked against the
-.RI \*q matchusb \*q
-shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers
-separated by a ':'. This is the same format as the
-.BR lsusb (8)
-program.
-.TP 7
-.BI "MatchDriver \*q" matchdriver \*q
-Check the case-sensitive string
-.RI \*q matchdriver \*q
-against the currently configured driver of the device. Ordering of sections
-using this entry is important since it will not match unless the driver has
-been set by the config backend or a previous
-.B InputClass
-section.
-.TP 7
-.BI "MatchTag \*q" matchtag \*q
-This entry can be used to check if tags assigned by the config backend
-matches the
-.RI \*q matchtag \*q
-pattern. A match is found if at least one of the tags given in
-.RI \*q matchtag \*q
-matches at least one of the tags assigned by the backend.
-.PP
-The second type of entry is used to match device types. These entries take a
-boolean argument similar to
-.B Option
-entries.
-.TP 7
-.BI "MatchIsKeyboard \*q" bool \*q
-.TP 7
-.BI "MatchIsPointer \*q" bool \*q
-.TP 7
-.BI "MatchIsJoystick \*q" bool \*q
-.TP 7
-.BI "MatchIsTablet \*q" bool \*q
-.TP 7
-.BI "MatchIsTouchpad \*q" bool \*q
-.TP 7
-.BI "MatchIsTouchscreen \*q" bool \*q
-.PP
-When an input device has been matched to the
-.B InputClass
-section, any
-.B Option
-entries are applied to the device. One
-.B InputClass
-specific
-.B Option
-is recognized. See the
-.B InputDevice
-section above for a description of the remaining
-.B Option
-entries.
-.TP 7
-.BI "Option \*qIgnore\*q \*q" boolean \*q
-This optional entry specifies that the device should be ignored entirely,
-and not added to the server. This can be useful when the device is handled
-by another program and no X events should be generated.
-.SH "DEVICE SECTION"
-The config file may have multiple
-.B Device
-sections.
-There must be at least one, for the video card being used.
-.PP
-.B Device
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qDevice\*q"
-.BI " Identifier \*q" name \*q
-.BI " Driver \*q" driver \*q
-.I " entries"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Driver
-entries are required in all
-.B Device
-sections. All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this graphics device.
-The
-.B Driver
-entry specifies the name of the driver to use for this graphics device.
-When using the loadable server, the driver module
-.RI \*q driver \*q
-will be loaded for each active
-.B Device
-section.
-A
-.B Device
-section is considered active if it is referenced by an active
-.B Screen
-section.
-.PP
-.B Device
-sections recognise some driver\-independent entries and
-.BR Options ,
-which are described here.
-Not all drivers make use of these
-driver\-independent entries, and many of those that do don't require them
-to be specified because the information is auto\-detected.
-See the individual graphics driver manual pages for further information
-about this, and for a description of the device\-specific options.
-Note that most of the
-.B Options
-listed here (but not the other entries) may be specified in the
-.B Screen
-section instead of here in the
-.B Device
-section.
-.TP 7
-.BI "BusID \*q" bus\-id \*q
-This specifies the bus location of the graphics card.
-For PCI/AGP cards,
-the
-.I bus\-id
-string has the form
-.BI PCI: bus : device : function
-(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card).
-This field is usually optional in single-head configurations when using
-the primary graphics card.
-In multi-head configurations, or when using a secondary graphics card in a
-single-head configuration, this entry is mandatory.
-Its main purpose is to make an unambiguous connection between the device
-section and the hardware it is representing.
-This information can usually be found by running the pciaccess tool
-scanpci.
-.TP 7
-.BI "Screen " number
-This option is mandatory for cards where a single PCI entity can drive more
-than one display (i.e., multiple CRTCs sharing a single graphics accelerator
-and video memory).
-One
-.B Device
-section is required for each head, and this
-parameter determines which head each of the
-.B Device
-sections applies to.
-The legal values of
-.I number
-range from 0 to one less than the total number of heads per entity.
-Most drivers require that the primary screen (0) be present.
-.TP 7
-.BI "Chipset \*q" chipset \*q
-This usually optional entry specifies the chipset used on the graphics
-board.
-In most cases this entry is not required because the drivers will probe the
-hardware to determine the chipset type.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "Ramdac \*q" ramdac\-type \*q
-This optional entry specifies the type of RAMDAC used on the graphics
-board.
-This is only used by a few of the drivers, and in most cases it is not
-required because the drivers will probe the hardware to determine the
-RAMDAC type where possible.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "DacSpeed " speed
-.TP 7
-.BI "DacSpeed " "speed\-8 speed\-16 speed\-24 speed\-32"
-This optional entry specifies the RAMDAC speed rating (which is usually
-printed on the RAMDAC chip).
-The speed is in MHz.
-When one value is given, it applies to all framebuffer pixel sizes.
-When multiple values are given, they apply to the framebuffer pixel sizes
-8, 16, 24 and 32 respectively.
-This is not used by many drivers, and only needs to be specified when the
-speed rating of the RAMDAC is different from the defaults built in to
-driver, or when the driver can't auto-detect the correct defaults.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "Clocks " "clock ..."
-specifies the pixel that are on your graphics board.
-The clocks are in MHz, and may be specified as a floating point number.
-The value is stored internally to the nearest kHz.
-The ordering of the clocks is important.
-It must match the order in which they are selected on the graphics board.
-Multiple
-.B Clocks
-lines may be specified, and each is concatenated to form the list.
-Most drivers do not use this entry, and it is only required for some older
-boards with non-programmable clocks.
-Don't specify this entry unless the driver-specific documentation explicitly
-recommends that you do.
-.TP
-.BI "ClockChip \*q" clockchip\-type \*q
-This optional entry is used to specify the clock chip type on graphics
-boards which have a programmable clock generator.
-Only a few __xservername__ drivers support programmable clock chips.
-For details, see the appropriate driver manual page.
-.TP 7
-.BI "VideoRam " "mem"
-This optional entry specifies the amount of video ram that is installed
-on the graphics board.
-This is measured in kBytes.
-In most cases this is not required because the __xservername__ server probes
-the graphics board to determine this quantity.
-The driver-specific documentation should indicate when it might be needed.
-.TP 7
-.BI "BiosBase " "baseaddress"
-This optional entry specifies the base address of the video BIOS for
-the VGA board.
-This address is normally auto-detected, and should only be specified if the
-driver-specific documentation recommends it.
-.TP 7
-.BI "MemBase " "baseaddress"
-This optional entry specifies the memory base address of a graphics
-board's linear frame buffer.
-This entry is not used by many drivers, and it should only be specified if
-the driver-specific documentation recommends it.
-.TP 7
-.BI "IOBase " "baseaddress"
-This optional entry specifies the IO base address.
-This entry is not used by many drivers, and it should only be specified if
-the driver-specific documentation recommends it.
-.TP 7
-.BI "ChipID " "id"
-This optional entry specifies a numerical ID representing the chip type.
-For PCI cards, it is usually the device ID.
-This can be used to override the auto-detection, but that should only be done
-when the driver-specific documentation recommends it.
-.TP 7
-.BI "ChipRev " "rev"
-This optional entry specifies the chip revision number.
-This can be used to override the auto-detection, but that should only be done
-when the driver-specific documentation recommends it.
-.TP 7
-.BI "TextClockFreq " "freq"
-This optional entry specifies the pixel clock frequency that is used
-for the regular text mode.
-The frequency is specified in MHz.
-This is rarely used.
-.TP 7
-.BI "Option \*qModeDebug\*q \*q" boolean \*q
-Enable printing of additional debugging information about modesetting to
-the server log.
-.ig
-.TP 7
-This optional entry allows an IRQ number to be specified.
-..
-.TP 7
-.B Options
-Option flags may be specified in the
-.B Device
-sections.
-These include driver\-specific options and driver\-independent options.
-The former are described in the driver\-specific documentation.
-Some of the latter are described below in the section about the
-.B Screen
-section, and they may also be included here.
-
-.SH "VIDEOADAPTOR SECTION"
-Nobody wants to say how this works.
-Maybe nobody knows ...
-
-.SH "MONITOR SECTION"
-The config file may have multiple
-.B Monitor
-sections.
-There should normally be at least one, for the monitor being used,
-but a default configuration will be created when one isn't specified.
-.PP
-.B Monitor
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qMonitor\*q"
-.BI " Identifier \*q" name \*q
-.I " entries"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The only mandatory entry in a
-.B Monitor
-section is the
-.B Identifier
-entry.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this monitor.
-The
-.B Monitor
-section may be used to provide information about the specifications of the
-monitor, monitor-specific
-.BR Options ,
-and information about the video modes to use with the monitor.
-.PP
-With RandR 1.2-enabled drivers, monitor sections may be tied to specific
-outputs of the video card. Using the name of the output defined by the video
-driver plus the identifier of a monitor section, one associates a monitor
-section with an output by adding an option to the Device section in the
-following format:
-
-.B Option \*qMonitor-outputname\*q \*qmonitorsection\*q
-
-(for example,
-.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q
-for a VGA output)
-.PP
-In the absence of specific association of monitor sections to outputs, if a
-monitor section is present the server will associate it with an output to
-preserve compatibility for previous single-head configurations.
-.PP
-Specifying video modes is optional because the server will use the DDC or other
-information provided by the monitor to automatically configure the list of
-modes available.
-When modes are specified explicitly in the
-.B Monitor
-section (with the
-.BR Modes ,
-.BR ModeLine ,
-or
-.B UseModes
-keywords), built-in modes with the same names are not included.
-Built-in modes with different names are, however, still implicitly included,
-when they meet the requirements of the monitor.
-.PP
-The entries that may be used in
-.B Monitor
-sections are described below.
-.TP 7
-.BI "VendorName \*q" vendor \*q
-This optional entry specifies the monitor's manufacturer.
-.TP 7
-.BI "ModelName \*q" model \*q
-This optional entry specifies the monitor's model.
-.TP 7
-.BI "HorizSync " "horizsync\-range"
-gives the range(s) of horizontal sync frequencies supported by the
-monitor.
-.I horizsync\-range
-may be a comma separated list of either discrete values or ranges of
-values.
-A range of values is two values separated by a dash.
-By default the values are in units of kHz.
-They may be specified in MHz or Hz
-if
-.B MHz
-or
-.B Hz
-is added to the end of the line.
-The data given here is used by the __xservername__ server to determine if video
-modes are within the specifications of the monitor.
-This information should be available in the monitor's handbook.
-If this entry is omitted, a default range of 28\-33kHz is used.
-.TP 7
-.BI "VertRefresh " "vertrefresh\-range"
-gives the range(s) of vertical refresh frequencies supported by the
-monitor.
-.I vertrefresh\-range
-may be a comma separated list of either discrete values or ranges of
-values.
-A range of values is two values separated by a dash.
-By default the values are in units of Hz.
-They may be specified in MHz or kHz
-if
-.B MHz
-or
-.B kHz
-is added to the end of the line.
-The data given here is used by the __xservername__ server to determine if video
-modes are within the specifications of the monitor.
-This information should be available in the monitor's handbook.
-If this entry is omitted, a default range of 43\-72Hz is used.
-.TP 7
-.BI "DisplaySize " "width height"
-This optional entry gives the width and height, in millimetres, of the
-picture area of the monitor.
-If given this is used to calculate the horizontal and vertical pitch (DPI) of
-the screen.
-.TP 7
-.BI "Gamma " "gamma\-value"
-.TP 7
-.BI "Gamma " "red\-gamma green\-gamma blue\-gamma"
-This is an optional entry that can be used to specify the gamma correction
-for the monitor.
-It may be specified as either a single value or as three separate RGB values.
-The values should be in the range 0.1 to 10.0, and the default is 1.0.
-Not all drivers are capable of using this information.
-.TP 7
-.BI "UseModes \*q" modesection\-id \*q
-Include the set of modes listed in the
-.B Modes
-section called
-.IR modesection\-id.
-This makes all of the modes defined in that section available for use by
-this monitor.
-.TP 7
-.BI "Mode \*q" name \*q
-This is an optional multi-line entry that can be used to provide
-definitions for video modes for the monitor.
-In most cases this isn't necessary because the built-in set of VESA standard
-modes will be sufficient.
-The
-.B Mode
-keyword indicates the start of a multi-line video mode description.
-The mode description is terminated with the
-.B EndMode
-keyword.
-The mode description consists of the following entries:
-.RS 7
-.TP 4
-.BI "DotClock " clock
-is the dot (pixel) clock rate to be used for the mode.
-.TP 4
-.BI "HTimings " "hdisp hsyncstart hsyncend htotal"
-specifies the horizontal timings for the mode.
-.TP 4
-.BI "VTimings " "vdisp vsyncstart vsyncend vtotal"
-specifies the vertical timings for the mode.
-.TP 4
-.BI "Flags \*q" flag \*q " ..."
-specifies an optional set of mode flags, each of which is a separate
-string in double quotes.
-.B \*qInterlace\*q
-indicates that the mode is interlaced.
-.B \*qDoubleScan\*q
-indicates a mode where each scanline is doubled.
-.B \*q+HSync\*q
-and
-.B \*q\-HSync\*q
-can be used to select the polarity of the HSync signal.
-.B \*q+VSync\*q
-and
-.B \*q\-VSync\*q
-can be used to select the polarity of the VSync signal.
-.B \*qComposite\*q
-can be used to specify composite sync on hardware where this is supported.
-Additionally, on some hardware,
-.B \*q+CSync\*q
-and
-.B \*q\-CSync\*q
-may be used to select the composite sync polarity.
-.TP 4
-.BI "HSkew " hskew
-specifies the number of pixels (towards the right edge of the screen) by
-which the display enable signal is to be skewed.
-Not all drivers use this information.
-This option might become necessary to override the default value supplied
-by the server (if any).
-\(lqRoving\(rq horizontal lines indicate this value needs to be increased.
-If the last few pixels on a scan line appear on the left of the screen,
-this value should be decreased.
-.TP 4
-.BI "VScan " vscan
-specifies the number of times each scanline is painted on the screen.
-Not all drivers use this information.
-Values less than 1 are treated as 1, which is the default.
-Generally, the
-.B \*qDoubleScan\*q
-.B Flag
-mentioned above doubles this value.
-.RE
-.TP 7
-.BI "ModeLine \*q" name \*q " mode\-description"
-This entry is a more compact version of the
-.B Mode
-entry, and it also can be used to specify video modes for the monitor.
-is a single line format for specifying video modes.
-In most cases this isn't necessary because the built\-in set of VESA
-standard modes will be sufficient.
-.PP
-.RS 7
-The
-.I mode\-description
-is in four sections, the first three of which are mandatory.
-The first is the dot (pixel) clock.
-This is a single number specifying the pixel clock rate for the mode in
-MHz.
-The second section is a list of four numbers specifying the horizontal
-timings.
-These numbers are the
-.IR hdisp ,
-.IR hsyncstart ,
-.IR hsyncend ,
-and
-.I htotal
-values.
-The third section is a list of four numbers specifying the vertical
-timings.
-These numbers are the
-.IR vdisp ,
-.IR vsyncstart ,
-.IR vsyncend ,
-and
-.I vtotal
-values.
-The final section is a list of flags specifying other characteristics of
-the mode.
-.B Interlace
-indicates that the mode is interlaced.
-.B DoubleScan
-indicates a mode where each scanline is doubled.
-.B +HSync
-and
-.B \-HSync
-can be used to select the polarity of the HSync signal.
-.B +VSync
-and
-.B \-VSync
-can be used to select the polarity of the VSync signal.
-.B Composite
-can be used to specify composite sync on hardware where this is supported.
-Additionally, on some hardware,
-.B +CSync
-and
-.B \-CSync
-may be used to select the composite sync polarity.
-The
-.B HSkew
-and
-.B VScan
-options mentioned above in the
-.B Modes
-entry description can also be used here.
-.RE
-.TP 7
-.BI "Option " "\*qDPMS\*q " \*qbool\*q
-This option controls whether the server should enable the DPMS extension
-for power management for this screen. The default is to enable the
-extension.
-.TP 7
-.BI "Option " "\*qSyncOnGreen\*q " \*qbool\*q
-This option controls whether the video card should drive the sync signal
-on the green color pin. Not all cards support this option, and most
-monitors do not require it. The default is off.
-.TP 7
-.BI "Option " "\*qPrimary\*q " \*qbool\*q
-This optional entry specifies that the monitor should be treated as the primary
-monitor. (RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qPreferredMode\*q " \*qstring\*q
-This optional entry specifies a mode to be marked as the preferred initial mode
-of the monitor.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qPosition\*q " "\*qx y\*q"
-This optional entry specifies the position of the monitor within the X
-screen.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qLeftOf\*q " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned to the
-left of the output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qRightOf\*q " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned to the
-right of the output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qAbove\*q " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned above the
-output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qBelow\*q " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned below the
-output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qEnable\*q " \*qbool\*q
-This optional entry specifies whether the monitor should be turned on
-at startup. By default, the server will attempt to enable all connected
-monitors.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qDefaultModes\*q " \*qbool\*q
-This optional entry specifies whether the server should add supported default
-modes to the list of modes offered on this monitor. By default, the server
-will add default modes; you should only disable this if you can guarantee
-that EDID will be available at all times, or if you have added custom modelines
-which the server can use.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qMinClock\*q " \*qfrequency\*q
-This optional entry specifies the minimum dot clock, in kHz, that is supported
-by the monitor.
-.TP 7
-.BI "Option " "\*qMaxClock\*q " \*qfrequency\*q
-This optional entry specifies the maximum dot clock, in kHz, that is supported
-by the monitor.
-.TP 7
-.BI "Option " "\*qIgnore\*q " \*qbool\*q
-This optional entry specifies that the monitor should be ignored entirely,
-and not reported through RandR. This is useful if the hardware reports the
-presence of outputs that don't exist.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qRotate\*q " \*qrotation\*q
-This optional entry specifies the initial rotation of the given monitor.
-Valid values for rotation are \*qnormal\*q, \*qleft\*q, \*qright\*q, and
-\*qinverted\*q.
-(RandR 1.2-supporting drivers only)
-
-.SH "MODES SECTION"
-The config file may have multiple
-.B Modes
-sections, or none.
-These sections provide a way of defining sets of video modes independently
-of the
-.B Monitor
-sections.
-.B Monitor
-sections may include the definitions provided in these sections by
-using the
-.B UseModes
-keyword.
-In most cases the
-.B Modes
-sections are not necessary because the built\-in set of VESA standard modes
-will be sufficient.
-.PP
-.B Modes
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qModes\*q"
-.BI " Identifier \*q" name \*q
-.I " entries"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-entry specifies the unique name for this set of mode descriptions.
-The other entries permitted in
-.B Modes
-sections are the
-.B Mode
-and
-.B ModeLine
-entries that are described above in the
-.B Monitor
-section.
-.SH "SCREEN SECTION"
-The config file may have multiple
-.B Screen
-sections.
-There must be at least one, for the \(lqscreen\(rq being used.
-A \(lqscreen\(rq represents the binding of a graphics device
-.RB ( Device
-section) and a monitor
-.RB ( Monitor
-section).
-A
-.B Screen
-section is considered \(lqactive\(rq if it is referenced by an active
-.B ServerLayout
-section or by the
-.B \-screen
-command line option.
-If neither of those is present, the first
-.B Screen
-section found in the config file is considered the active one.
-.PP
-.B Screen
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qScreen\*q"
-.BI " Identifier \*q" name \*q
-.BI " Device \*q" devid \*q
-.BI " Monitor \*q" monid \*q
-.I " entries"
-.I " ..."
-.BI " SubSection \*qDisplay\*q"
-.I " entries"
-.I " ...
-.B " EndSubSection"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Device
-entries are mandatory.
-All others are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this screen.
-The
-.B Screen
-section provides information specific to the whole screen, including
-screen\-specific
-.BR Options .
-In multi\-head configurations, there will be multiple active
-.B Screen
-sections, one for each head.
-The entries available
-for this section are:
-.TP 7
-.BI "Device \*q" device\-id \*q
-This mandatory entry specifies the
-.B Device
-section to be used for this screen.
-This is what ties a specific graphics card to a screen.
-The
-.I device\-id
-must match the
-.B Identifier
-of a
-.B Device
-section in the config file.
-.TP 7
-.BI "Monitor \*q" monitor\-id \*q
-specifies which monitor description is to be used for this screen.
-If a
-.B Monitor
-name is not specified, a default configuration is used.
-Currently the default configuration may not function as expected on all
-platforms.
-.TP 7
-.BI "VideoAdaptor \*q" xv\-id \*q
-specifies an optional Xv video adaptor description to be used with this
-screen.
-.TP 7
-.BI "DefaultDepth " depth
-specifies which color depth the server should use by default.
-The
-.B \-depth
-command line option can be used to override this.
-If neither is specified, the default depth is driver\-specific, but in most
-cases is 8.
-.TP 7
-.BI "DefaultFbBpp " bpp
-specifies which framebuffer layout to use by default.
-The
-.B \-fbbpp
-command line option can be used to override this.
-In most cases the driver will chose the best default value for this.
-The only case where there is even a choice in this value is for depth 24,
-where some hardware supports both a packed 24 bit framebuffer layout and a
-sparse 32 bit framebuffer layout.
-.TP 7
-.B Options
-Various
-.B Option
-flags may be specified in the
-.B Screen
-section.
-Some are driver\-specific and are described in the driver documentation.
-Others are driver\-independent, and will eventually be described here.
-.\" XXX These should really be in an xaa man page.
-.TP 7
-.BI "Option \*qAccel\*q"
-Enables XAA (X Acceleration Architecture), a mechanism that makes video cards'
-2D hardware acceleration available to the __xservername__ server.
-This option is on by default, but it may be necessary to turn it off if
-there are bugs in the driver.
-There are many options to disable specific accelerated operations, listed
-below.
-Note that disabling an operation will have no effect if the operation is
-not accelerated (whether due to lack of support in the hardware or in the
-driver).
-.TP 7
-.BI "Option \*qInitPrimary\*q \*q" boolean \*q
-Use the Int10 module to initialize the primary graphics card.
-Normally, only secondary cards are soft-booted using the Int10 module, as the
-primary card has already been initialized by the BIOS at boot time.
-Default: false.
-.TP 7
-.BI "Option \*qNoInt10\*q \*q" boolean \*q
-Disables the Int10 module, a module that uses the int10 call to the BIOS
-of the graphics card to initialize it.
-Default: false.
-.TP 7
-.BI "Option \*qNoMTRR\*q"
-Disables MTRR (Memory Type Range Register) support, a feature of modern
-processors which can improve video performance by a factor of up to 2.5.
-Some hardware has buggy MTRR support, and some video drivers have been
-known to exhibit problems when MTRR's are used.
-.TP 7
-.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in system memory (using a memory\-mapped aperture).
-.TP 7
-.BI "Option \*qXaaNoColor8x8PatternFillRect\*q"
-Disables accelerated fills of a rectangular region with a full\-color
-pattern.
-.TP 7
-.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q"
-Disables accelerated fills of a trapezoidal region with a full\-color
-pattern.
-.TP 7
-.BI "Option \*qXaaNoDashedBresenhamLine\*q"
-Disables accelerated dashed Bresenham line draws.
-.TP 7
-.BI "Option \*qXaaNoDashedTwoPointLine\*q"
-Disables accelerated dashed line draws between two arbitrary points.
-.TP 7
-.BI "Option \*qXaaNoImageWriteRect\*q"
-Disables accelerated transfers of full\-color rectangular patterns from
-system memory to video memory (using a memory\-mapped aperture).
-.TP 7
-.BI "Option \*qXaaNoMono8x8PatternFillRect\*q"
-Disables accelerated fills of a rectangular region with a monochrome
-pattern.
-.TP 7
-.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q"
-Disables accelerated fills of a trapezoidal region with a monochrome
-pattern.
-.TP 7
-.BI "Option \*qXaaNoOffscreenPixmaps\*q"
-Disables accelerated draws into pixmaps stored in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoPixmapCache\*q"
-Disables caching of patterns in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in system memory (one scan line at a time).
-.TP 7
-.BI "Option \*qXaaNoScanlineImageWriteRect\*q"
-Disables accelerated transfers of full\-color rectangular patterns from
-system memory to video memory (one scan line at a time).
-.TP 7
-.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoScreenToScreenCopy\*q"
-Disables accelerated copies of rectangular regions from one part of
-video memory to another part of video memory.
-.TP 7
-.BI "Option \*qXaaNoSolidBresenhamLine\*q"
-Disables accelerated solid Bresenham line draws.
-.TP 7
-.BI "Option \*qXaaNoSolidFillRect\*q"
-Disables accelerated solid\-color fills of rectangles.
-.TP 7
-.BI "Option \*qXaaNoSolidFillTrap\*q"
-Disables accelerated solid\-color fills of Bresenham trapezoids.
-.TP 7
-.BI "Option \*qXaaNoSolidHorVertLine\*q"
-Disables accelerated solid horizontal and vertical line draws.
-.TP 7
-.BI "Option \*qXaaNoSolidTwoPointLine\*q"
-Disables accelerated solid line draws between two arbitrary points.
-.PP
-Each
-.B Screen
-section may optionally contain one or more
-.B Display
-subsections.
-Those subsections provide depth/fbbpp specific configuration information,
-and the one chosen depends on the depth and/or fbbpp that is being used for
-the screen.
-The
-.B Display
-subsection format is described in the section below.
-
-.SH "DISPLAY SUBSECTION"
-Each
-.B Screen
-section may have multiple
-.B Display
-subsections.
-The \(lqactive\(rq
-.B Display
-subsection is the first that matches the depth and/or fbbpp values being
-used, or failing that, the first that has neither a depth or fbbpp value
-specified.
-The
-.B Display
-subsections are optional.
-When there isn't one that matches the depth and/or fbbpp values being used,
-all the parameters that can be specified here fall back to their defaults.
-.PP
-.B Display
-subsections have the following format:
-.PP
-.RS 4
-.nf
-.B " SubSection \*qDisplay\*q"
-.BI " Depth " depth
-.I " entries"
-.I " ..."
-.B " EndSubSection"
-.fi
-.RE
-.TP 7
-.BI "Depth " depth
-This entry specifies what colour depth the
-.B Display
-subsection is to be used for.
-This entry is usually specified, but it may be omitted to create a match\-all
-.B Display
-subsection or when wishing to match only against the
-.B FbBpp
-parameter.
-The range of
-.I depth
-values that are allowed depends on the driver.
-Most drivers support 8, 15, 16 and 24.
-Some also support 1 and/or 4, and some may support other values (like 30).
-Note:
-.I depth
-means the number of bits in a pixel that are actually used to determine
-the pixel colour.
-32 is not a valid
-.I depth
-value.
-Most hardware that uses 32 bits per pixel only uses 24 of them to hold the
-colour information, which means that the colour depth is 24, not 32.
-.TP 7
-.BI "FbBpp " bpp
-This entry specifies the framebuffer format this
-.B Display
-subsection is to be used for.
-This entry is only needed when providing depth 24 configurations that allow
-a choice between a 24 bpp packed framebuffer format and a 32bpp sparse
-framebuffer format.
-In most cases this entry should not be used.
-.TP 7
-.BI "Weight " "red\-weight green\-weight blue\-weight"
-This optional entry specifies the relative RGB weighting to be used
-for a screen is being used at depth 16 for drivers that allow multiple
-formats.
-This may also be specified from the command line with the
-.B \-weight
-option (see
-.BR __xservername__(__appmansuffix__)).
-.TP 7
-.BI "Virtual " "xdim ydim"
-This optional entry specifies the virtual screen resolution to be used.
-.I xdim
-must be a multiple of either 8 or 16 for most drivers, and a multiple
-of 32 when running in monochrome mode.
-The given value will be rounded down if this is not the case.
-Video modes which are too large for the specified virtual size will be
-rejected.
-If this entry is not present, the virtual screen resolution will be set to
-accommodate all the valid video modes given in the
-.B Modes
-entry.
-Some drivers/hardware combinations do not support virtual screens.
-Refer to the appropriate driver\-specific documentation for details.
-.TP 7
-.BI "ViewPort " "x0 y0"
-This optional entry sets the upper left corner of the initial display.
-This is only relevant when the virtual screen resolution is different
-from the resolution of the initial video mode.
-If this entry is not given, then the initial display will be centered in
-the virtual display area.
-.TP 7
-.BI "Modes \*q" mode\-name \*q " ..."
-This optional entry specifies the list of video modes to use.
-Each
-.I mode\-name
-specified must be in double quotes.
-They must correspond to those specified or referenced in the appropriate
-.B Monitor
-section (including implicitly referenced built\-in VESA standard modes).
-The server will delete modes from this list which don't satisfy various
-requirements.
-The first valid mode in this list will be the default display mode for
-startup.
-The list of valid modes is converted internally into a circular list.
-It is possible to switch to the next mode with
-.B Ctrl+Alt+Keypad\-Plus
-and to the previous mode with
-.BR Ctrl+Alt+Keypad\-Minus .
-When this entry is omitted, the valid modes referenced by the appropriate
-.B Monitor
-section will be used. If the
-.B Monitor
-section contains no modes, then the selection will be taken from the
-built-in VESA standard modes.
-.TP 7
-.BI "Visual \*q" visual\-name \*q
-This optional entry sets the default root visual type.
-This may also be specified from the command line (see the
-.BR Xserver(__appmansuffix__)
-man page).
-The visual types available for depth 8 are (default is
-.BR PseudoColor ):
-.PP
-.RS 11
-.nf
-.B StaticGray
-.B GrayScale
-.B StaticColor
-.B PseudoColor
-.B TrueColor
-.B DirectColor
-.fi
-.RE
-.PP
-.RS 7
-The visual type available for the depths 15, 16 and 24 are (default is
-.BR TrueColor ):
-.PP
-.RS 4
-.nf
-.B TrueColor
-.B DirectColor
-.fi
-.RE
-.PP
-Not all drivers support
-.B DirectColor
-at these depths.
-.PP
-The visual types available for the depth 4 are (default is
-.BR StaticColor ):
-.PP
-.RS 4
-.nf
-.B StaticGray
-.B GrayScale
-.B StaticColor
-.B PseudoColor
-.fi
-.RE
-.PP
-The visual type available for the depth 1 (monochrome) is
-.BR StaticGray .
-.RE
-.TP 7
-.BI "Black " "red green blue"
-This optional entry allows the \(lqblack\(rq colour to be specified.
-This is only supported at depth 1.
-The default is black.
-.TP 7
-.BI "White " "red green blue"
-This optional entry allows the \(lqwhite\(rq colour to be specified.
-This is only supported at depth 1.
-The default is white.
-.TP 7
-.B Options
-Option flags may be specified in the
-.B Display
-subsections.
-These may include driver\-specific options and driver\-independent options.
-The former are described in the driver\-specific documentation.
-Some of the latter are described above in the section about the
-.B Screen
-section, and they may also be included here.
-.SH "SERVERLAYOUT SECTION"
-The config file may have multiple
-.B ServerLayout
-sections.
-A \(lqserver layout\(rq represents the binding of one or more screens
-.RB ( Screen
-sections) and one or more input devices
-.RB ( InputDevice
-sections) to form a complete configuration.
-In multi\-head configurations, it also specifies the relative layout of the
-heads.
-A
-.B ServerLayout
-section is considered \(lqactive\(rq if it is referenced by the
-.B \-layout
-command line option or by an
-.B "Option \*qDefaultServerLayout\*q"
-entry in the
-.B ServerFlags
-section (the former takes precedence over the latter).
-If those options are not used, the first
-.B ServerLayout
-section found in the config file is considered the active one.
-If no
-.B ServerLayout
-sections are present, the single active screen and two active (core)
-input devices are selected as described in the relevant sections above.
-.PP
-.B ServerLayout
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B "Section \*qServerLayout\*q"
-.BI " Identifier \*q" name \*q
-.BI " Screen \*q" screen\-id \*q
-.I " ..."
-.BI " InputDevice \*q" idev\-id \*q
-.I " ..."
-.I " options"
-.I " ..."
-.B "EndSection"
-.fi
-.RE
-.PP
-Each
-.B ServerLayout
-section must have an
-.B Identifier
-entry and at least one
-.B Screen
-entry.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this server layout.
-The
-.B ServerLayout
-section provides information specific to the whole session, including
-session\-specific
-.BR Options .
-The
-.B ServerFlags
-options (described above) may be specified here, and ones given here
-override those given in the
-.B ServerFlags
-section.
-.PP
-The entries that may be used in this section are described here.
-.TP 7
-.BI "Screen " "screen\-num" " \*qscreen\-id\*q " "position\-information"
-One of these entries must be given for each screen being used in
-a session.
-The
-.I screen\-id
-field is mandatory, and specifies the
-.B Screen
-section being referenced.
-The
-.I screen\-num
-field is optional, and may be used to specify the screen number
-in multi\-head configurations.
-When this field is omitted, the screens will be numbered in the order that
-they are listed in.
-The numbering starts from 0, and must be consecutive.
-The
-.I position\-information
-field describes the way multiple screens are positioned.
-There are a number of different ways that this information can be provided:
-.RS 7
-.TP 4
-.I "x y"
-.TP 4
-.BI "Absolute " "x y"
-These both specify that the upper left corner's coordinates are
-.RI ( x , y ).
-The
-.B Absolute
-keyword is optional.
-Some older versions of XFree86 (4.2 and earlier) don't recognise the
-.B Absolute
-keyword, so it's safest to just specify the coordinates without it.
-.TP 4
-.BI "RightOf \*q" screen\-id \*q
-.TP 4
-.BI "LeftOf \*q" screen\-id \*q
-.TP 4
-.BI "Above \*q" screen\-id \*q
-.TP 4
-.BI "Below \*q" screen\-id \*q
-.TP 4
-.BI "Relative \*q" screen\-id \*q " x y"
-These give the screen's location relative to another screen.
-The first four position the screen immediately to the right, left, above or
-below the other screen.
-When positioning to the right or left, the top edges are aligned.
-When positioning above or below, the left edges are aligned.
-The
-.B Relative
-form specifies the offset of the screen's origin (upper left corner)
-relative to the origin of another screen.
-.RE
-.TP 7
-.BI "InputDevice \*q" idev\-id "\*q \*q" option \*q " ..."
-One of these entries should be given for each input device being used in
-a session.
-Normally at least two are required, one each for the core pointer and
-keyboard devices.
-If either of those is missing, suitable
-.B InputDevice
-entries are searched for using the method described above in the
-.B INPUTDEVICE
-section. The
-.I idev\-id
-field is mandatory, and specifies the name of the
-.B InputDevice
-section being referenced.
-Multiple
-.I option
-fields may be specified, each in double quotes.
-The options permitted here are any that may also be given in the
-.B InputDevice
-sections.
-Normally only session\-specific input device options would be used here.
-The most commonly used options are:
-.PP
-.RS 11
-.nf
-.B \*qCorePointer\*q
-.B \*qCoreKeyboard\*q
-.B \*qSendCoreEvents\*q
-.fi
-.RE
-.PP
-.RS 7
-and the first two should normally be used to indicate the core pointer
-and core keyboard devices respectively.
-.RE
-.TP 7
-.B Options
-In addition to the following, any option permitted in the
-.B ServerFlags
-section may also be specified here.
-When the same option appears in both places, the value given here overrides
-the one given in the
-.B ServerFlags
-section.
-.TP 7
-.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q
-Restrict device resets to the specified
-.IR bus\-id .
-See the
-.B BusID
-option (described in
-.BR "DEVICE SECTION" ,
-above) for the format of the
-.I bus\-id
-parameter.
-This option overrides
-.BR SingleCard ,
-if specified.
-At present, only PCI devices can be isolated in this manner.
-.TP 7
-.BI "Option \*qSingleCard\*q \*q" boolean \*q
-As
-.BR IsolateDevice ,
-except that the bus ID of the first device in the layout is used.
-.PP
-Here is an example of a
-.B ServerLayout
-section for a dual headed configuration with two mice:
-.PP
-.RS 4
-.nf
-.B "Section \*qServerLayout\*q"
-.B " Identifier \*qLayout 1\*q"
-.B " Screen \*qMGA 1\*q"
-.B " Screen \*qMGA 2\*q RightOf \*qMGA 1\*q"
-.B " InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q"
-.B " InputDevice \*qMouse 1\*q \*qCorePointer\*q"
-.B " InputDevice \*qMouse 2\*q \*qSendCoreEvents\*q"
-.B " Option \*qBlankTime\*q \*q5\*q"
-.B "EndSection"
-.fi
-.RE
-.SH "DRI SECTION"
-This optional section is used to provide some information for the
-Direct Rendering Infrastructure.
-Details about the format of this section can be found on-line at
-.IR <http://dri.freedesktop.org/> .
-.SH "VENDOR SECTION"
-The optional
-.B Vendor
-section may be used to provide vendor\-specific configuration information.
-Multiple
-.B Vendor
-sections may be present, and they may contain an
-.B Identifier
-entry and multiple
-.B Option
-flags.
-The data therein is not used in this release.
-.PP
-.SH "SEE ALSO"
-General:
-.BR X (__miscmansuffix__),
-.BR Xserver (__appmansuffix__),
-.BR __xservername__ (__appmansuffix__),
-.BR cvt (__appmansuffix__),
-.BR gtf (__appmansuffix__).
-.PP
-.B "Not all modules or interfaces are available on all platforms."
-.PP
-Display drivers:
-.BR apm (__drivermansuffix__),
-.BR ati (__drivermansuffix__),
-.BR chips (__drivermansuffix__),
-.BR cirrus (__drivermansuffix__),
-.BR cyrix (__drivermansuffix__),
-.BR fbdev (__drivermansuffix__),
-.BR glide (__drivermansuffix__),
-.BR glint (__drivermansuffix__),
-.BR i128 (__drivermansuffix__),
-.BR i740 (__drivermansuffix__),
-.BR imstt (__drivermansuffix__),
-.BR intel (__drivermansuffix__),
-.BR mga (__drivermansuffix__),
-.BR neomagic (__drivermansuffix__),
-.BR nv (__drivermansuffix__),
-.BR openchrome (__drivermansuffix__),
-.BR r128 (__drivermansuffix__),
-.BR radeon (__drivermansuffix__),
-.BR rendition (__drivermansuffix__),
-.BR savage (__drivermansuffix__),
-.BR s3virge (__drivermansuffix__),
-.BR siliconmotion (__drivermansuffix__),
-.BR sis (__drivermansuffix__),
-.BR sisusb (__drivermansuffix__),
-.BR sunbw2 (__drivermansuffix__),
-.BR suncg14 (__drivermansuffix__),
-.BR suncg3 (__drivermansuffix__),
-.BR suncg6 (__drivermansuffix__),
-.BR sunffb (__drivermansuffix__),
-.BR sunleo (__drivermansuffix__),
-.BR suntcx (__drivermansuffix__),
-.BR tdfx (__drivermansuffix__),
-.\" .BR tga (__drivermansuffix__),
-.BR trident (__drivermansuffix__),
-.BR tseng (__drivermansuffix__),
-.BR vesa (__drivermansuffix__),
-.BR vmware (__drivermansuffix__),
-.BR voodoo (__drivermansuffix__),
-.BR wsfb (__drivermansuffix__),
-.BR xgi (__drivermansuffix__),
-.BR xgixp (__drivermansuffix__).
-.PP
-Input drivers:
-.BR acecad (__drivermansuffix__),
-.BR citron (__drivermansuffix__),
-.BR elographics (__drivermansuffix__),
-.BR evdev (__drivermansuffix__),
-.BR fpit (__drivermansuffix__),
-.BR joystick (__drivermansuffix__),
-.BR kbd (__drivermansuffix__),
-.BR mousedrv (__drivermansuffix__),
-.BR mutouch (__drivermansuffix__),
-.BR penmount (__drivermansuffix__),
-.BR synaptics (__drivermansuffix__),
-.BR vmmouse (__drivermansuffix__),
-.BR void (__drivermansuffix__),
-.BR wacom (__drivermansuffix__).
-.PP
-Other modules and interfaces:
-.BR exa (__drivermansuffix__),
-.BR fbdevhw (__drivermansuffix__),
-.\" .BR shadowfb (__drivermansuffix__),
-.BR v4l (__drivermansuffix__).
-.br
-.SH AUTHORS
-This manual page was largely rewritten by David Dawes
-.IR <dawes@xfree86.org> .
+.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH __xconfigfile__ __filemansuffix__ __vendorversion__ +.SH NAME +__xconfigfile__ and __xconfigdir__ \- configuration files for +__xservername__ X server +.SH INTRODUCTION +.B __xservername__ +supports several mechanisms for supplying/obtaining configuration and +run-time parameters: command line options, environment variables, the +__xconfigfile__ and __xconfigdir__ configuration files, auto-detection, +and fallback defaults. When the same information is supplied in more +than one way, the highest precedence mechanism is used. The list of +mechanisms is ordered from highest precedence to lowest. Note that not +all parameters can be supplied via all methods. The available command +line options and environment variables (and some defaults) are +described in the Xserver(__appmansuffix__) and +__xservername__(__appmansuffix__) manual pages. Most configuration file +parameters, with their defaults, are described below. Driver and module +specific configuration parameters are described in the relevant driver +or module manual page. +.SH DESCRIPTION +.B __xservername__ +uses a configuration file called +.I __xconfigfile__ +and files ending in the suffix +.I .conf +from the directory +.I __xconfigdir__ +for its initial setup. +The +.I __xconfigfile__ +configuration file is searched for in the following places when the +server is started as a normal user: +.PP +.RS 4 +.nf +.IR /etc/X11/ <cmdline> +.IR __projectroot__/etc/X11/ <cmdline> +.IB /etc/X11/ $XORGCONFIG +.IB __projectroot__/etc/X11/ $XORGCONFIG +.I /etc/X11/__xconfigfile__ +.I /etc/__xconfigfile__ +.IR __projectroot__/etc/X11/__xconfigfile__. <hostname> +.I __projectroot__/etc/X11/__xconfigfile__ +.IR __projectroot__/lib/X11/__xconfigfile__. <hostname> +.I __projectroot__/lib/X11/__xconfigfile__ +.fi +.RE +.PP +where +.I <cmdline> +is a relative path (with no \(lq..\(rq components) specified with the +.B \-config +command line option, +.B $XORGCONFIG +is the relative path (with no \(lq..\(rq components) specified by that +environment variable, and +.I <hostname> +is the machine's hostname as reported by +.BR gethostname (__libmansuffix__). +.PP +When the __xservername__ server is started by the \(lqroot\(rq user, the config file +search locations are as follows: +.PP +.RS 4 +.nf +<cmdline> +.IR /etc/X11/ <cmdline> +.IR __projectroot__/etc/X11/ <cmdline> +.B $XORGCONFIG +.IB /etc/X11/ $XORGCONFIG +.IB __projectroot__/etc/X11/ $XORGCONFIG +.I /etc/X11/__xconfigfile__ +.I /etc/__xconfigfile__ +.IR __projectroot__/etc/X11/__xconfigfile__. <hostname> +.I __projectroot__/etc/X11/__xconfigfile__ +.IR __projectroot__/lib/X11/__xconfigfile__. <hostname> +.I __projectroot__/lib/X11/__xconfigfile__ +.fi +.RE +.PP +where +.I <cmdline> +is the path specified with the +.B \-config +command line option (which may be absolute or relative), +.B $XORGCONFIG +is the path specified by that +environment variable (absolute or relative), +.B $HOME +is the path specified by that environment variable (usually the home +directory), and +.I <hostname> +is the machine's hostname as reported by +.BR gethostname (__libmansuffix__). +.PP +Additional configuration files are searched for in the following +directories when the server is started as a normal user: +.PP +.RS 4 +.nf +.IR /etc/X11/ <cmdline> +.IR __sysconfdir__/X11/ <cmdline> +.I /etc/X11/__xconfigdir__ +.I __sysconfdir__/X11/__xconfigdir__ +.fi +.RE +.PP +where +.I <cmdline> +is a relative path (with no \(lq..\(rq components) specified with the +.B \-configdir +command line option. +.PP +When the __xservername__ server is started by the \(lqroot\(rq user, the +config directory search locations are as follows: +.PP +.RS 4 +.nf +<cmdline> +.IR /etc/X11/ <cmdline> +.IR __sysconfdir__/X11/ <cmdline> +.I /etc/X11/__xconfigdir__ +.I __sysconfdir__/X11/__xconfigdir__ +.fi +.RE +.PP +where +.I <cmdline> +is the path specified with the +.B \-configdir +command line option (which may be absolute or relative). +.PP +Finally, configuration files will also be searched for in directories +reserved for system use. These are to separate configuration files from +the vendor or 3rd party packages from those of local administration. +These files are found in the following directories: +.PP +.RS 4 +.nf +.I /usr/share/X11/__xconfigdir__ +.I __datadir__/X11/__xconfigdir__ +.fi +.RE +.PP +The +.I __xconfigfile__ +and +.I __xconfigdir__ +files are composed of a number of sections which may be present in any order, +or omitted to use default configuration values. +Each section has the form: +.PP +.RS 4 +.nf +.BI "Section \*q" SectionName \*q +.RI " " SectionEntry + ... +.B EndSection +.fi +.RE +.PP +The section names are: +.PP +.RS 4 +.nf +.BR "Files " "File pathnames" +.BR "ServerFlags " "Server flags" +.BR "Module " "Dynamic module loading" +.BR "Extensions " "Extension enabling" +.BR "InputDevice " "Input device description" +.BR "InputClass " "Input class description" +.BR "Device " "Graphics device description" +.BR "VideoAdaptor " "Xv video adaptor description" +.BR "Monitor " "Monitor description" +.BR "Modes " "Video modes descriptions" +.BR "Screen " "Screen configuration" +.BR "ServerLayout " "Overall layout" +.BR "DRI " "DRI\-specific configuration" +.BR "Vendor " "Vendor\-specific configuration" +.fi +.RE +.PP +The following obsolete section names are still recognised for compatibility +purposes. +In new config files, the +.B InputDevice +section should be used instead. +.PP +.RS 4 +.nf +.BR "Keyboard " "Keyboard configuration" +.BR "Pointer " "Pointer/mouse configuration" +.fi +.RE +.PP +The old +.B XInput +section is no longer recognised. +.PP +The +.B ServerLayout +sections are at the highest level. +They bind together the input and output devices that will be used in a session. +The input devices are described in the +.B InputDevice +sections. +Output devices usually consist of multiple independent components (e.g., +a graphics board and a monitor). +These multiple components are bound together in the +.B Screen +sections, and it is these that are referenced by the +.B ServerLayout +section. +Each +.B Screen +section binds together a graphics board and a monitor. +The graphics boards are described in the +.B Device +sections, and the monitors are described in the +.B Monitor +sections. +.PP +Config file keywords are case\-insensitive, and \(lq_\(rq characters are +ignored. +Most strings (including +.B Option +names) are also case-insensitive, and insensitive to white space and +\(lq_\(rq characters. +.PP +Each config file entry usually takes up a single line in the file. They +consist of a keyword, which is possibly followed by one or more arguments, +with the number and types of the arguments depending on the keyword. +The argument types are: +.PP +.RS 4 +.nf +.BR "Integer " "an integer number in decimal, hex or octal" +.BR "Real " "a floating point number" +.BR "String " "a string enclosed in double quote marks (\*q)" +.fi +.RE +.PP +Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values +with \(lq0\(rq. +.PP +A special keyword called +.B Option +may be used to provide free\-form data to various components of the server. +The +.B Option +keyword takes either one or two string arguments. +The first is the option name, and the optional second argument is the +option value. +Some commonly used option value types include: +.PP +.RS 4 +.nf +.BR "Integer " "an integer number in decimal, hex or octal" +.BR "Real " "a floating point number" +.BR "String " "a sequence of characters" +.BR "Boolean " "a boolean value (see below)" +.BR "Frequency " "a frequency value (see below)" +.fi +.RE +.PP +Note that +.I all +.B Option +values, not just strings, must be enclosed in quotes. +.PP +Boolean options may optionally have a value specified. +When no value is specified, the option's value is +.BR TRUE . +The following boolean option values are recognised as +.BR TRUE : +.PP +.RS 4 +.BR 1 , +.BR on , +.BR true , +.B yes +.RE +.PP +and the following boolean option values are recognised as +.BR FALSE : +.PP +.RS 4 +.BR 0 , +.BR off , +.BR false , +.B no +.RE +.PP +If an option name is prefixed with +.RB \*q No \*q, +then the option value is negated. +.PP +Example: the following option entries are equivalent: +.PP +.RS 4 +.nf +.B "Option \*qAccel\*q \*qOff\*q" +.B "Option \*qNoAccel\*q" +.B "Option \*qNoAccel\*q \*qOn\*q" +.B "Option \*qAccel\*q \*qfalse\*q" +.B "Option \*qAccel\*q \*qno\*q" +.fi +.RE +.PP +Frequency option values consist of a real number that is optionally +followed by one of the following frequency units: +.PP +.RS 4 +.BR Hz , +.BR k , +.BR kHz , +.BR M , +.B MHz +.RE +.PP +When the unit name is omitted, the correct units will be determined from +the value and the expectations of the appropriate range of the value. +It is recommended that the units always be specified when using frequency +option values to avoid any errors in determining the value. +.SH "FILES SECTION" +The +.B Files +section is used to specify some path names required by the server. +Some of these paths can also be set from the command line (see +.BR Xserver (__appmansuffix__) +and +.BR __xservername__ (__appmansuffix__)). +The command line settings override the values specified in the config +file. +The +.B Files +section is optional, as are all of the entries that may appear in it. +.PP +The entries that can appear in this section are: +.TP 7 +.BI "FontPath \*q" path \*q +sets the search path for fonts. +This path is a comma separated list of font path elements which the __xservername__ +server searches for font databases. +Multiple +.B FontPath +entries may be specified, and they will be concatenated to build up the +fontpath used by the server. Font path elements can be absolute +directory paths, catalogue directories or a font server identifier. The +formats of the later two are explained below: +.PP +.RS 7 +Catalogue directories: +.PP +.RS 4 +Catalogue directories can be specified using the prefix \fBcatalogue:\fR +before the directory name. The directory can then be populated with +symlinks pointing to the real font directories, using the following +syntax in the symlink name: +.PP +.RS 4 +.IR <identifier> : [attribute]: pri= <priority> +.RE +.PP +where +.I <identifier> +is an alphanumeric identifier, +.I [attribute] +is an attribute which will be passed to the underlying FPE and +.I <priority> +is a number used to order the fontfile FPEs. Examples: +.PP +.RS 4 +.nf +.I 75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi +.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript +.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc +.fi +.PP +.RE .RE .RE +.PP +.RS 7 +Font server identifiers: +.PP +.RS 4 +Font server identifiers have the form: +.RS 4 +.PP +.IR <trans> / <hostname> : <port\-number> +.RE +.PP +where +.I <trans> +is the transport type to use to connect to the font server (e.g., +.B unix +for UNIX\-domain sockets or +.B tcp +for a TCP/IP connection), +.I <hostname> +is the hostname of the machine running the font server, and +.I <port\-number> +is the port number that the font server is listening on (usually 7100). +.RE +.PP +When this entry is not specified in the config file, the server falls back +to the compiled\-in default font path, which contains the following +font path elements (which can be set inside a catalogue directory): +.PP +.RS 4 +.nf +.I __datadir__/fonts/X11/misc/ +.I __datadir__/fonts/X11/TTF/ +.I __datadir__/fonts/X11/OTF/ +.I __datadir__/fonts/X11/Type1/ +.I __datadir__/fonts/X11/100dpi/ +.I __datadir__/fonts/X11/75dpi/ +.fi +.RE +.PP +Font path elements that are found to be invalid are removed from the +font path when the server starts up. +.RE +.TP 7 +.BI "ModulePath \*q" path \*q +sets the search path for loadable __xservername__ server modules. +This path is a comma separated list of directories which the __xservername__ server +searches for loadable modules loading in the order specified. +Multiple +.B ModulePath +entries may be specified, and they will be concatenated to build the +module search path used by the server. The default module path is +.PP +.RS 11 +__modulepath__ +.RE +.\" The LogFile keyword is not currently implemented +.ig +.TP 7 +.BI "LogFile \*q" path \*q +sets the name of the __xservername__ server log file. +The default log file name is +.PP +.RS 11 +.RI __logdir__/__xservername__. <n> .log +.RE +.PP +.RS 7 +where +.I <n> +is the display number for the __xservername__ server. +.. +.TP 7 +.BI "XkbDir \*q" path \*q +sets the base directory for keyboard layout files. The +.B \-xkbdir +command line option can be used to override this. The default directory is +.PP +.RS 11 +__xkbdir__ +.RE +.SH "SERVERFLAGS SECTION" +In addition to options specific to this section (described below), the +.B ServerFlags +section is used to specify some global +__xservername__ server options. +All of the entries in this section are +.BR Options , +although for compatibility purposes some of the old style entries are +still recognised. +Those old style entries are not documented here, and using them is +discouraged. +The +.B ServerFlags +section is optional, as are the entries that may be specified in it. +.PP +.B Options +specified in this section (with the exception of the +.B \*qDefaultServerLayout\*q +.BR Option ) +may be overridden by +.B Options +specified in the active +.B ServerLayout +section. +Options with command line equivalents are overridden when their command +line equivalent is used. +The options recognised by this section are: +.TP 7 +.BI "Option \*qDefaultServerLayout\*q \*q" layout\-id \*q +This specifies the default +.B ServerLayout +section to use in the absence of the +.B \-layout +command line option. +.TP 7 +.BI "Option \*qNoTrapSignals\*q \*q" boolean \*q +This prevents the __xservername__ server from trapping a range of unexpected fatal +signals and exiting cleanly. +Instead, the __xservername__ server will die and drop core where the fault occurred. +The default behaviour is for the __xservername__ server to exit cleanly, but still drop a +core file. +In general you never want to use this option unless you are debugging an __xservername__ +server problem and know how to deal with the consequences. +.TP 7 +.BI "Option \*qUseSIGIO\*q \*q" boolean \*q +This controls whether the __xservername__ server requests that events from +input devices be reported via a SIGIO signal handler (also known as SIGPOLL +on some platforms), or only reported via the standard select(3) loop. +The default behaviour is platform specific. In general you do not want to +use this option unless you are debugging the __xservername__ server, or +working around a specific bug until it is fixed, and understand the +consequences. +.TP 7 +.BI "Option \*qDontVTSwitch\*q \*q" boolean \*q +This disallows the use of the +.BI Ctrl+Alt+F n +sequence (where +.RI F n +refers to one of the numbered function keys). +That sequence is normally used to switch to another \*qvirtual terminal\*q +on operating systems that have this feature. +When this option is enabled, that key sequence has no special meaning and +is passed to clients. +Default: off. +.TP 7 +.BI "Option \*qDontZap\*q \*q" boolean \*q +This disallows the use of the +.B Terminate_Server +XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options). +This action is normally used to terminate the __xservername__ server. +When this option is enabled, the action has no effect. +Default: off. +.TP 7 +.BI "Option \*qDontZoom\*q \*q" boolean \*q +This disallows the use of the +.B Ctrl+Alt+Keypad\-Plus +and +.B Ctrl+Alt+Keypad\-Minus +sequences. +These sequences allows you to switch between video modes. +When this option is enabled, those key sequences have no special meaning +and are passed to clients. +Default: off. +.TP 7 +.BI "Option \*qDisableVidModeExtension\*q \*q" boolean \*q +This disables the parts of the VidMode extension used by the xvidtune client +that can be used to change the video modes. +Default: the VidMode extension is enabled. +.TP 7 +.BI "Option \*qAllowNonLocalXvidtune\*q \*q" boolean \*q +This allows the xvidtune client (and other clients that use the VidMode +extension) to connect from another host. +Default: off. +.TP 7 +.BI "Option \*qAllowMouseOpenFail\*q \*q" boolean \*q +This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__) +drivers to not report failure if the mouse device can't be opened/initialised. +It has no effect on the evdev(__drivermansuffix__) or other drivers. +Default: false. +.TP 7 +.BI "Option \*qVTSysReq\*q \*q" boolean \*q +enables the SYSV\-style VT switch sequence for non\-SYSV systems +which support VT switching. +This sequence is +.B Alt\-SysRq +followed by a function key +.RB ( Fn ). +This prevents the __xservername__ server trapping the +keys used for the default VT switch sequence, which means that clients can +access them. +Default: off. +.TP 7 +.BI "Option \*qBlankTime\*q \*q" time \*q +sets the inactivity timeout for the +.B blank +phase of the screensaver. +.I time +is in minutes. +This is equivalent to the __xservername__ server's +.B \-s +flag, and the value can be changed at run\-time with +.BR xset(__appmansuffix__). +Default: 10 minutes. +.TP 7 +.BI "Option \*qStandbyTime\*q \*q" time \*q +sets the inactivity timeout for the +.B standby +phase of DPMS mode. +.I time +is in minutes, and the value can be changed at run\-time with +.BR xset(__appmansuffix__). +Default: 10 minutes. +This is only suitable for VESA DPMS compatible monitors, and may not be +supported by all video drivers. +It is only enabled for screens that have the +.B \*qDPMS\*q +option set (see the MONITOR section below). +.TP 7 +.BI "Option \*qSuspendTime\*q \*q" time \*q +sets the inactivity timeout for the +.B suspend +phase of DPMS mode. +.I time +is in minutes, and the value can be changed at run\-time with +.BR xset(__appmansuffix__). +Default: 10 minutes. +This is only suitable for VESA DPMS compatible monitors, and may not be +supported by all video drivers. +It is only enabled for screens that have the +.B \*qDPMS\*q +option set (see the MONITOR section below). +.TP 7 +.BI "Option \*qOffTime\*q \*q" time \*q +sets the inactivity timeout for the +.B off +phase of DPMS mode. +.I time +is in minutes, and the value can be changed at run\-time with +.BR xset(__appmansuffix__). +Default: 10 minutes. +This is only suitable for VESA DPMS compatible monitors, and may not be +supported by all video drivers. +It is only enabled for screens that have the +.B \*qDPMS\*q +option set (see the MONITOR section below). +.TP 7 +.BI "Option \*qPixmap\*q \*q" bpp \*q +This sets the pixmap format to use for depth 24. +Allowed values for +.I bpp +are 24 and 32. +Default: 32 unless driver constraints don't allow this (which is rare). +Note: some clients don't behave well when this value is set to 24. +.TP 7 +.BI "Option \*qPC98\*q \*q" boolean \*q +Specify that the machine is a Japanese PC\-98 machine. +This should not be enabled for anything other than the Japanese\-specific +PC\-98 architecture. +Default: auto\-detected. +.TP 7 +.BI "Option \*qNoPM\*q \*q" boolean \*q +Disables something to do with power management events. +Default: PM enabled on platforms that support it. +.TP 7 +.BI "Option \*qXinerama\*q \*q" boolean \*q +enable or disable XINERAMA extension. +Default is disabled. +.TP 7 +.BI "Option \*qAIGLX\*q \*q" boolean \*q +enable or disable AIGLX. AIGLX is enabled by default. +.TP 7 +.BI "Option \*qDRI2\*q \*q" boolean \*q +enable or disable DRI2. DRI2 is disabled by default. +.TP 7 +.BI "Option \*qGlxVisuals\*q \*q" string \*q +This option controls how many GLX visuals the GLX modules sets up. +The default value is +.BR "typical" , +which will setup up a typical subset of +the GLXFBConfigs provided by the driver as GLX visuals. Other options are +.BR "minimal" , +which will set up the minimal set allowed by the GLX specification and +.BR "all" +which will setup GLX visuals for all GLXFBConfigs. +.TP 7 +.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q +Include the default font path even if other paths are specified in +xorg.conf. If enabled, other font paths are included as well. Enabled by +default. +.TP 7 +.BI "Option \*qIgnoreABI\*q \*q" boolean \*q +Allow modules built for a different, potentially incompatible version of +the X server to load. Disabled by default. +.TP 7 +.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q +If this option is disabled, then no devices will be added from HAL events. +Enabled by default. +.TP 7 +.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q +If this option is disabled, then the devices will be added (and the +DevicePresenceNotify event sent), but not enabled, thus leaving policy up +to the client. +Enabled by default. +.TP 7 +.BI "Option \*qLog\*q \*q" string \*q +This option controls whether the log is flushed and/or synced to disk after +each message. +Possible values are +.B flush +or +.BR sync . +Unset by default. +.SH "MODULE SECTION" +The +.B Module +section is used to specify which __xservername__ server modules should be loaded. +This section is ignored when the __xservername__ server is built in static form. +The type of modules normally loaded in this section are __xservername__ server +extension modules. +Most other module types are loaded automatically when they are needed via +other mechanisms. +The +.B Module +section is optional, as are all of the entries that may be specified in +it. +.PP +Entries in this section may be in two forms. +The first and most commonly used form is an entry that uses the +.B Load +keyword, as described here: +.TP 7 +.BI "Load \*q" modulename \*q +This instructs the server to load the module called +.IR modulename . +The module name given should be the module's standard name, not the +module file name. +The standard name is case\-sensitive, and does not include the \(lqlib\(rq +prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes. +.PP +.RS 7 +Example: the DRI extension module can be loaded with the following entry: +.PP +.RS 4 +.B "Load \*qdri\*q" +.RE +.RE +.TP 7 +.BI "Disable \*q" modulename \*q +This instructs the server to not load the module called +.IR modulename . +Some modules are loaded by default in the server, and this overrides that +default. If a +.B Load +instruction is given for the same module, it overrides the +.B Disable +instruction and the module is loaded. The module name given should be the +module's standard name, not the module file name. As with the +.B Load +instruction, the standard name is case-sensitive, and does not include the +"lib" prefix, or the ".a", ".o", or ".so" suffixes. +.PP +The second form of entry is a +.BR SubSection, +with the subsection name being the module name, and the contents of the +.B SubSection +being +.B Options +that are passed to the module when it is loaded. +.PP +Example: the extmod module (which contains a miscellaneous group of +server extensions) can be loaded, with the XFree86\-DGA extension +disabled by using the following entry: +.PP +.RS 4 +.nf +.B "SubSection \*qextmod\*q" +.B " Option \*qomit XFree86\-DGA\*q" +.B EndSubSection +.fi +.RE +.PP +Modules are searched for in each directory specified in the +.B ModulePath +search path, and in the drivers, extensions, input, internal, and +multimedia subdirectories of each of those directories. +In addition to this, operating system specific subdirectories of all +the above are searched first if they exist. +.PP +To see what extension modules are available, check the extensions +subdirectory under: +.PP +.RS 4 +.nf +__modulepath__ +.fi +.RE +.PP +The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq, +and \(lqrecord\(rq extension modules are loaded automatically, if they +are present, unless disabled with \*qDisable\*q entries. +It is recommended +that at very least the \(lqextmod\(rq extension module be loaded. +If it isn't, some commonly used server extensions (like the SHAPE +extension) will not be available. +.SH "EXTENSIONS SECTION" +The +.B Extensions +section is used to specify which X11 protocol extensions should be enabled +or disabled. +The +.B Extensions +section is optional, as are all of the entries that may be specified in +it. +.PP +Entries in this section are listed as Option statements with the name of +the extension as the first argument, and a boolean value as the second. +The extension name is case\-sensitive, and matches the form shown in the output +of \*qXorg -extension ?\*q. +.PP +.RS 7 +Example: the MIT-SHM extension can be disabled with the following entry: +.PP +.RS 4 +.nf +.B "Section \*qExtensions\*q" +.B " Option \*qMIT-SHM\*q \*qDisable\*q" +.B "EndSection" +.fi +.RE +.RE +.SH "INPUTDEVICE SECTION" +The config file may have multiple +.B InputDevice +sections. +Recent X servers employ input hotplugging to add input devices, with the HAL +backend being the default backend for X servers since 1.4. It is usually not +necessary to provide +.B InputDevice +sections in the xorg.conf if hotplugging is enabled. +.PP +If hotplugging is disabled, there will normally +be at least two: one for the core (primary) keyboard +and one for the core pointer. +If either of these two is missing, a default configuration for the missing +ones will be used. In the absence of an explicitly specified core input +device, the first +.B InputDevice +marked as +.B CorePointer +(or +.BR CoreKeyboard ) +is used. +If there is no match there, the first +.B InputDevice +that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used. +The final fallback is to use built\-in default configurations. +Currently the default configuration may not work as expected on all platforms. +.PP +.B InputDevice +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qInputDevice\*q" +.BI " Identifier \*q" name \*q +.BI " Driver \*q" inputdriver \*q +.I " options" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The +.B Identifier +and +.B Driver +entries are required in all +.B InputDevice +sections. +All other entries are optional. +.PP +The +.B Identifier +entry specifies the unique name for this input device. +The +.B Driver +entry specifies the name of the driver to use for this input device. +When using the loadable server, the input driver module +.RI \*q inputdriver \*q +will be loaded for each active +.B InputDevice +section. +An +.B InputDevice +section is considered active if it is referenced by an active +.B ServerLayout +section, if it is referenced by the +.B \-keyboard +or +.B \-pointer +command line options, or if it is selected implicitly as the core pointer +or keyboard device in the absence of such explicit references. +The most commonly used input drivers are +.BR evdev (__drivermansuffix__) +on Linux systems, and +.BR kbd (__drivermansuffix__) +and +.BR mousedrv (__drivermansuffix__) +on other platforms. +.PP +.PP +.B InputDevice +sections recognise some driver\-independent +.BR Options , +which are described here. +See the individual input driver manual pages for a description of the +device\-specific options. +.TP 7 +.BI "Option \*qAutoServerLayout\*q \*q" boolean \*q +Always add the device to the ServerLayout section used by this instance of +the server. This affects implied layouts as well as explicit layouts +specified in the configuration and/or on the command line. +.TP 7 +.BI "Option \*qCorePointer\*q" +Deprecated, see +.B Floating +.TP 7 +.BI "Option \*qCoreKeyboard\*q" +Deprecated, see +.B Floating +.TP 7 +.BI "Option \*qAlwaysCore\*q \*q" boolean \*q +Deprecated, see +.B Floating +.TP 7 +.BI "Option \*qSendCoreEvents\*q \*q" boolean \*q +Deprecated, see +.B Floating + +.TP 7 +.BI "Option \*qFloating\*q \*q" boolean \*q +When enabled, the input device is set up floating and does not +report events through any master device or control a cursor. The device is +only available to clients using the X Input Extension API. This option is +disabled by default. +The options +.B CorePointer, +.B CoreKeyboard, +.B AlwaysCore, +and +.B SendCoreEvents, +are the inverse of option +.B Floating +(i.e. +.B SendCoreEvents \*qon\*q +is equivalent to +.B Floating \*qoff\*q +). + +This option controls the startup behavior only, a device +may be reattached or set floating at runtime. +.PP +For pointing devices, the following options control how the pointer +is accelerated or decelerated with respect to physical device motion. Most of +these can be adjusted at runtime, see the xinput(1) man page for details. Only +the most important acceleration options are discussed here. +.TP 7 +.BI "Option \*qAccelerationProfile\*q \*q" integer \*q +Select the profile. In layman's terms, the profile constitutes the "feeling" of +the acceleration. More formally, it defines how the transfer function (actual +acceleration as a function of current device velocity and acceleration controls) +is constructed. This is mainly a matter of personal preference. +.PP +.RS 6 +.nf +.B " 0 classic (mostly compatible)" +.B "-1 none (only constant deceleration is applied)" +.B " 1 device-dependent" +.B " 2 polynomial (polynomial function)" +.B " 3 smooth linear (soft knee, then linear)" +.B " 4 simple (normal when slow, otherwise accelerated)" +.B " 5 power (power function)" +.B " 6 linear (more speed, more acceleration)" +.B " 7 limited (like linear, but maxes out at threshold)" +.fi +.RE +.TP 7 +.BI "Option \*qConstantDeceleration\*q \*q" real \*q +Makes the pointer go +.B deceleration +times slower than normal. Most useful for high-resolution devices. +.TP 7 +.BI "Option \*qAdaptiveDeceleration\*q \*q" real \*q +Allows to actually decelerate the pointer when going slow. At most, it will be +.B adaptive deceleration +times slower. Enables precise pointer placement without sacrificing speed. +.TP 7 +.BI "Option \*qAccelerationScheme\*q \*q" string \*q +Selects the scheme, which is the underlying algorithm. +.PP +.RS 7 +.nf +.B "predictable default algorithm (behaving more predictable)" +.B "lightweight old acceleration code (as specified in the X protocol spec)" +.B "none no acceleration or deceleration" +.fi +.RE +.TP 7 +.BI "Option \*qAccelerationNumerator\*q \*q" integer \*q +.TP 7 +.BI "Option \*qAccelerationDenominator\*q \*q" integer \*q +Set numerator and denominator of the acceleration factor. The acceleration +factor is a rational which, together with threshold, can be used to tweak +profiles to suit the users needs. The +.B simple +and +.B limited +profiles use it directly (i.e. they accelerate by the factor), for other +profiles it should hold that a higher acceleration factor leads to a faster +pointer. Typically, 1 is unaccelerated and values up to 5 are sensible. +.TP 7 +.BI "Option \*qAccelerationThreshold\*q \*q" integer \*q +Set the threshold, which is roughly the velocity (usually device units per 10 +ms) required for acceleration to become effective. The precise effect varies +with the profile however. + +.SH "INPUTCLASS SECTION" +The config file may have multiple +.B InputClass +sections. +These sections are optional and are used to provide configuration for a +class of input devices as they are automatically added. An input device can +match more than one +.B InputClass +section. Each class can override settings from a previous class, so it is +best to arrange the sections with the most generic matches first. +.PP +.B InputClass +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qInputClass\*q" +.BI " Identifier \*q" name \*q +.I " entries" +.I " ..." +.I " options" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The +.B Identifier +entry is required in all +.B InputClass +sections. +All other entries are optional. +.PP +The +.B Identifier +entry specifies the unique name for this input class. +The +.B Driver +entry specifies the name of the driver to use for this input device. +After all classes have been examined, the +.RI \*q inputdriver \*q +module from the first +.B Driver +entry will be enabled when using the loadable server. +.PP +When an input device is automatically added, its characteristics are +checked against all +.B InputClass +sections. Each section can contain optional entries to narrow the match +of the class. If none of the optional entries appear, the +.B InputClass +section is generic and will match any input device. If more than one of +these entries appear, they all must match for the configuration to apply. +.PP +There are two types of match entries used in +.B InputClass +sections. The first allows various tokens to be matched against attributes +of the device. An entry can be constructed to match attributes from different +devices by separating arguments with a '|' character. Multiple entries of the +same type may be supplied to add multiple matching conditions on the same +attribute. For example: +.PP +.RS 4 +.nf +.B "Section \*qInputClass\*q" +.B " Identifier \*qMy Class\*q" +.B " # product string must contain example and +.B " # either gizmo or gadget +.B " MatchProduct \*qexample\*q +.B " MatchProduct \*qgizmo|gadget\*q +.I " ..." +.B "EndSection" +.fi +.RE +.TP 7 +.BI "MatchProduct \*q" matchproduct \*q +This entry can be used to check if the substring +.RI \*q matchproduct \*q +occurs in the device's product name. +.TP 7 +.BI "MatchVendor \*q" matchvendor \*q +This entry can be used to check if the substring +.RI \*q matchvendor \*q +occurs in the device's vendor name. +.TP 7 +.BI "MatchDevicePath \*q" matchdevice \*q +This entry can be used to check if the device file matches the +.RI \*q matchdevice \*q +pathname pattern. +.TP 7 +.BI "MatchOS \*q" matchos \*q +This entry can be used to check if the operating system matches the +case-insensitive +.RI \*q matchos \*q +string. This entry is only supported on platforms providing the +.BR uname (2) +system call. +.TP 7 +.BI "MatchPnPID \*q" matchpnp \*q +The device's Plug and Play (PnP) ID can be checked against the +.RI \*q matchpnp \*q +shell wildcard pattern. +.TP 7 +.BI "MatchUSBID \*q" matchusb \*q +The device's USB ID can be checked against the +.RI \*q matchusb \*q +shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers +separated by a ':'. This is the same format as the +.BR lsusb (8) +program. +.TP 7 +.BI "MatchDriver \*q" matchdriver \*q +Check the case-sensitive string +.RI \*q matchdriver \*q +against the currently configured driver of the device. Ordering of sections +using this entry is important since it will not match unless the driver has +been set by the config backend or a previous +.B InputClass +section. +.TP 7 +.BI "MatchTag \*q" matchtag \*q +This entry can be used to check if tags assigned by the config backend +matches the +.RI \*q matchtag \*q +pattern. A match is found if at least one of the tags given in +.RI \*q matchtag \*q +matches at least one of the tags assigned by the backend. +.PP +The second type of entry is used to match device types. These entries take a +boolean argument similar to +.B Option +entries. +.TP 7 +.BI "MatchIsKeyboard \*q" bool \*q +.TP 7 +.BI "MatchIsPointer \*q" bool \*q +.TP 7 +.BI "MatchIsJoystick \*q" bool \*q +.TP 7 +.BI "MatchIsTablet \*q" bool \*q +.TP 7 +.BI "MatchIsTouchpad \*q" bool \*q +.TP 7 +.BI "MatchIsTouchscreen \*q" bool \*q +.PP +When an input device has been matched to the +.B InputClass +section, any +.B Option +entries are applied to the device. One +.B InputClass +specific +.B Option +is recognized. See the +.B InputDevice +section above for a description of the remaining +.B Option +entries. +.TP 7 +.BI "Option \*qIgnore\*q \*q" boolean \*q +This optional entry specifies that the device should be ignored entirely, +and not added to the server. This can be useful when the device is handled +by another program and no X events should be generated. +.SH "DEVICE SECTION" +The config file may have multiple +.B Device +sections. +There must be at least one, for the video card being used. +.PP +.B Device +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" name \*q +.BI " Driver \*q" driver \*q +.I " entries" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The +.B Identifier +and +.B Driver +entries are required in all +.B Device +sections. All other entries are optional. +.PP +The +.B Identifier +entry specifies the unique name for this graphics device. +The +.B Driver +entry specifies the name of the driver to use for this graphics device. +When using the loadable server, the driver module +.RI \*q driver \*q +will be loaded for each active +.B Device +section. +A +.B Device +section is considered active if it is referenced by an active +.B Screen +section. +.PP +.B Device +sections recognise some driver\-independent entries and +.BR Options , +which are described here. +Not all drivers make use of these +driver\-independent entries, and many of those that do don't require them +to be specified because the information is auto\-detected. +See the individual graphics driver manual pages for further information +about this, and for a description of the device\-specific options. +Note that most of the +.B Options +listed here (but not the other entries) may be specified in the +.B Screen +section instead of here in the +.B Device +section. +.TP 7 +.BI "BusID \*q" bus\-id \*q +This specifies the bus location of the graphics card. +For PCI/AGP cards, +the +.I bus\-id +string has the form +.BI PCI: bus : device : function +(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card). +This field is usually optional in single-head configurations when using +the primary graphics card. +In multi-head configurations, or when using a secondary graphics card in a +single-head configuration, this entry is mandatory. +Its main purpose is to make an unambiguous connection between the device +section and the hardware it is representing. +This information can usually be found by running the pciaccess tool +scanpci. +.TP 7 +.BI "Screen " number +This option is mandatory for cards where a single PCI entity can drive more +than one display (i.e., multiple CRTCs sharing a single graphics accelerator +and video memory). +One +.B Device +section is required for each head, and this +parameter determines which head each of the +.B Device +sections applies to. +The legal values of +.I number +range from 0 to one less than the total number of heads per entity. +Most drivers require that the primary screen (0) be present. +.TP 7 +.BI "Chipset \*q" chipset \*q +This usually optional entry specifies the chipset used on the graphics +board. +In most cases this entry is not required because the drivers will probe the +hardware to determine the chipset type. +Don't specify it unless the driver-specific documentation recommends that you +do. +.TP 7 +.BI "Ramdac \*q" ramdac\-type \*q +This optional entry specifies the type of RAMDAC used on the graphics +board. +This is only used by a few of the drivers, and in most cases it is not +required because the drivers will probe the hardware to determine the +RAMDAC type where possible. +Don't specify it unless the driver-specific documentation recommends that you +do. +.TP 7 +.BI "DacSpeed " speed +.TP 7 +.BI "DacSpeed " "speed\-8 speed\-16 speed\-24 speed\-32" +This optional entry specifies the RAMDAC speed rating (which is usually +printed on the RAMDAC chip). +The speed is in MHz. +When one value is given, it applies to all framebuffer pixel sizes. +When multiple values are given, they apply to the framebuffer pixel sizes +8, 16, 24 and 32 respectively. +This is not used by many drivers, and only needs to be specified when the +speed rating of the RAMDAC is different from the defaults built in to +driver, or when the driver can't auto-detect the correct defaults. +Don't specify it unless the driver-specific documentation recommends that you +do. +.TP 7 +.BI "Clocks " "clock ..." +specifies the pixel that are on your graphics board. +The clocks are in MHz, and may be specified as a floating point number. +The value is stored internally to the nearest kHz. +The ordering of the clocks is important. +It must match the order in which they are selected on the graphics board. +Multiple +.B Clocks +lines may be specified, and each is concatenated to form the list. +Most drivers do not use this entry, and it is only required for some older +boards with non-programmable clocks. +Don't specify this entry unless the driver-specific documentation explicitly +recommends that you do. +.TP +.BI "ClockChip \*q" clockchip\-type \*q +This optional entry is used to specify the clock chip type on graphics +boards which have a programmable clock generator. +Only a few __xservername__ drivers support programmable clock chips. +For details, see the appropriate driver manual page. +.TP 7 +.BI "VideoRam " "mem" +This optional entry specifies the amount of video ram that is installed +on the graphics board. +This is measured in kBytes. +In most cases this is not required because the __xservername__ server probes +the graphics board to determine this quantity. +The driver-specific documentation should indicate when it might be needed. +.TP 7 +.BI "BiosBase " "baseaddress" +This optional entry specifies the base address of the video BIOS for +the VGA board. +This address is normally auto-detected, and should only be specified if the +driver-specific documentation recommends it. +.TP 7 +.BI "MemBase " "baseaddress" +This optional entry specifies the memory base address of a graphics +board's linear frame buffer. +This entry is not used by many drivers, and it should only be specified if +the driver-specific documentation recommends it. +.TP 7 +.BI "IOBase " "baseaddress" +This optional entry specifies the IO base address. +This entry is not used by many drivers, and it should only be specified if +the driver-specific documentation recommends it. +.TP 7 +.BI "ChipID " "id" +This optional entry specifies a numerical ID representing the chip type. +For PCI cards, it is usually the device ID. +This can be used to override the auto-detection, but that should only be done +when the driver-specific documentation recommends it. +.TP 7 +.BI "ChipRev " "rev" +This optional entry specifies the chip revision number. +This can be used to override the auto-detection, but that should only be done +when the driver-specific documentation recommends it. +.TP 7 +.BI "TextClockFreq " "freq" +This optional entry specifies the pixel clock frequency that is used +for the regular text mode. +The frequency is specified in MHz. +This is rarely used. +.TP 7 +.BI "Option \*qModeDebug\*q \*q" boolean \*q +Enable printing of additional debugging information about modesetting to +the server log. +.ig +.TP 7 +This optional entry allows an IRQ number to be specified. +.. +.TP 7 +.B Options +Option flags may be specified in the +.B Device +sections. +These include driver\-specific options and driver\-independent options. +The former are described in the driver\-specific documentation. +Some of the latter are described below in the section about the +.B Screen +section, and they may also be included here. + +.SH "VIDEOADAPTOR SECTION" +Nobody wants to say how this works. +Maybe nobody knows ... + +.SH "MONITOR SECTION" +The config file may have multiple +.B Monitor +sections. +There should normally be at least one, for the monitor being used, +but a default configuration will be created when one isn't specified. +.PP +.B Monitor +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qMonitor\*q" +.BI " Identifier \*q" name \*q +.I " entries" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The only mandatory entry in a +.B Monitor +section is the +.B Identifier +entry. +.PP +The +.B Identifier +entry specifies the unique name for this monitor. +The +.B Monitor +section may be used to provide information about the specifications of the +monitor, monitor-specific +.BR Options , +and information about the video modes to use with the monitor. +.PP +With RandR 1.2-enabled drivers, monitor sections may be tied to specific +outputs of the video card. Using the name of the output defined by the video +driver plus the identifier of a monitor section, one associates a monitor +section with an output by adding an option to the Device section in the +following format: + +.B Option \*qMonitor-outputname\*q \*qmonitorsection\*q + +(for example, +.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q +for a VGA output) +.PP +In the absence of specific association of monitor sections to outputs, if a +monitor section is present the server will associate it with an output to +preserve compatibility for previous single-head configurations. +.PP +Specifying video modes is optional because the server will use the DDC or other +information provided by the monitor to automatically configure the list of +modes available. +When modes are specified explicitly in the +.B Monitor +section (with the +.BR Modes , +.BR ModeLine , +or +.B UseModes +keywords), built-in modes with the same names are not included. +Built-in modes with different names are, however, still implicitly included, +when they meet the requirements of the monitor. +.PP +The entries that may be used in +.B Monitor +sections are described below. +.TP 7 +.BI "VendorName \*q" vendor \*q +This optional entry specifies the monitor's manufacturer. +.TP 7 +.BI "ModelName \*q" model \*q +This optional entry specifies the monitor's model. +.TP 7 +.BI "HorizSync " "horizsync\-range" +gives the range(s) of horizontal sync frequencies supported by the +monitor. +.I horizsync\-range +may be a comma separated list of either discrete values or ranges of +values. +A range of values is two values separated by a dash. +By default the values are in units of kHz. +They may be specified in MHz or Hz +if +.B MHz +or +.B Hz +is added to the end of the line. +The data given here is used by the __xservername__ server to determine if video +modes are within the specifications of the monitor. +This information should be available in the monitor's handbook. +If this entry is omitted, a default range of 28\-33kHz is used. +.TP 7 +.BI "VertRefresh " "vertrefresh\-range" +gives the range(s) of vertical refresh frequencies supported by the +monitor. +.I vertrefresh\-range +may be a comma separated list of either discrete values or ranges of +values. +A range of values is two values separated by a dash. +By default the values are in units of Hz. +They may be specified in MHz or kHz +if +.B MHz +or +.B kHz +is added to the end of the line. +The data given here is used by the __xservername__ server to determine if video +modes are within the specifications of the monitor. +This information should be available in the monitor's handbook. +If this entry is omitted, a default range of 43\-72Hz is used. +.TP 7 +.BI "DisplaySize " "width height" +This optional entry gives the width and height, in millimetres, of the +picture area of the monitor. +If given this is used to calculate the horizontal and vertical pitch (DPI) of +the screen. +.TP 7 +.BI "Gamma " "gamma\-value" +.TP 7 +.BI "Gamma " "red\-gamma green\-gamma blue\-gamma" +This is an optional entry that can be used to specify the gamma correction +for the monitor. +It may be specified as either a single value or as three separate RGB values. +The values should be in the range 0.1 to 10.0, and the default is 1.0. +Not all drivers are capable of using this information. +.TP 7 +.BI "UseModes \*q" modesection\-id \*q +Include the set of modes listed in the +.B Modes +section called +.IR modesection\-id. +This makes all of the modes defined in that section available for use by +this monitor. +.TP 7 +.BI "Mode \*q" name \*q +This is an optional multi-line entry that can be used to provide +definitions for video modes for the monitor. +In most cases this isn't necessary because the built-in set of VESA standard +modes will be sufficient. +The +.B Mode +keyword indicates the start of a multi-line video mode description. +The mode description is terminated with the +.B EndMode +keyword. +The mode description consists of the following entries: +.RS 7 +.TP 4 +.BI "DotClock " clock +is the dot (pixel) clock rate to be used for the mode. +.TP 4 +.BI "HTimings " "hdisp hsyncstart hsyncend htotal" +specifies the horizontal timings for the mode. +.TP 4 +.BI "VTimings " "vdisp vsyncstart vsyncend vtotal" +specifies the vertical timings for the mode. +.TP 4 +.BI "Flags \*q" flag \*q " ..." +specifies an optional set of mode flags, each of which is a separate +string in double quotes. +.B \*qInterlace\*q +indicates that the mode is interlaced. +.B \*qDoubleScan\*q +indicates a mode where each scanline is doubled. +.B \*q+HSync\*q +and +.B \*q\-HSync\*q +can be used to select the polarity of the HSync signal. +.B \*q+VSync\*q +and +.B \*q\-VSync\*q +can be used to select the polarity of the VSync signal. +.B \*qComposite\*q +can be used to specify composite sync on hardware where this is supported. +Additionally, on some hardware, +.B \*q+CSync\*q +and +.B \*q\-CSync\*q +may be used to select the composite sync polarity. +.TP 4 +.BI "HSkew " hskew +specifies the number of pixels (towards the right edge of the screen) by +which the display enable signal is to be skewed. +Not all drivers use this information. +This option might become necessary to override the default value supplied +by the server (if any). +\(lqRoving\(rq horizontal lines indicate this value needs to be increased. +If the last few pixels on a scan line appear on the left of the screen, +this value should be decreased. +.TP 4 +.BI "VScan " vscan +specifies the number of times each scanline is painted on the screen. +Not all drivers use this information. +Values less than 1 are treated as 1, which is the default. +Generally, the +.B \*qDoubleScan\*q +.B Flag +mentioned above doubles this value. +.RE +.TP 7 +.BI "ModeLine \*q" name \*q " mode\-description" +This entry is a more compact version of the +.B Mode +entry, and it also can be used to specify video modes for the monitor. +is a single line format for specifying video modes. +In most cases this isn't necessary because the built\-in set of VESA +standard modes will be sufficient. +.PP +.RS 7 +The +.I mode\-description +is in four sections, the first three of which are mandatory. +The first is the dot (pixel) clock. +This is a single number specifying the pixel clock rate for the mode in +MHz. +The second section is a list of four numbers specifying the horizontal +timings. +These numbers are the +.IR hdisp , +.IR hsyncstart , +.IR hsyncend , +and +.I htotal +values. +The third section is a list of four numbers specifying the vertical +timings. +These numbers are the +.IR vdisp , +.IR vsyncstart , +.IR vsyncend , +and +.I vtotal +values. +The final section is a list of flags specifying other characteristics of +the mode. +.B Interlace +indicates that the mode is interlaced. +.B DoubleScan +indicates a mode where each scanline is doubled. +.B +HSync +and +.B \-HSync +can be used to select the polarity of the HSync signal. +.B +VSync +and +.B \-VSync +can be used to select the polarity of the VSync signal. +.B Composite +can be used to specify composite sync on hardware where this is supported. +Additionally, on some hardware, +.B +CSync +and +.B \-CSync +may be used to select the composite sync polarity. +The +.B HSkew +and +.B VScan +options mentioned above in the +.B Modes +entry description can also be used here. +.RE +.TP 7 +.BI "Option " "\*qDPMS\*q " \*qbool\*q +This option controls whether the server should enable the DPMS extension +for power management for this screen. The default is to enable the +extension. +.TP 7 +.BI "Option " "\*qSyncOnGreen\*q " \*qbool\*q +This option controls whether the video card should drive the sync signal +on the green color pin. Not all cards support this option, and most +monitors do not require it. The default is off. +.TP 7 +.BI "Option " "\*qPrimary\*q " \*qbool\*q +This optional entry specifies that the monitor should be treated as the primary +monitor. (RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qPreferredMode\*q " \*qstring\*q +This optional entry specifies a mode to be marked as the preferred initial mode +of the monitor. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qPosition\*q " "\*qx y\*q" +This optional entry specifies the position of the monitor within the X +screen. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qLeftOf\*q " \*qoutput\*q +This optional entry specifies that the monitor should be positioned to the +left of the output (not monitor) of the given name. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qRightOf\*q " \*qoutput\*q +This optional entry specifies that the monitor should be positioned to the +right of the output (not monitor) of the given name. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qAbove\*q " \*qoutput\*q +This optional entry specifies that the monitor should be positioned above the +output (not monitor) of the given name. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qBelow\*q " \*qoutput\*q +This optional entry specifies that the monitor should be positioned below the +output (not monitor) of the given name. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qEnable\*q " \*qbool\*q +This optional entry specifies whether the monitor should be turned on +at startup. By default, the server will attempt to enable all connected +monitors. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qDefaultModes\*q " \*qbool\*q +This optional entry specifies whether the server should add supported default +modes to the list of modes offered on this monitor. By default, the server +will add default modes; you should only disable this if you can guarantee +that EDID will be available at all times, or if you have added custom modelines +which the server can use. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qMinClock\*q " \*qfrequency\*q +This optional entry specifies the minimum dot clock, in kHz, that is supported +by the monitor. +.TP 7 +.BI "Option " "\*qMaxClock\*q " \*qfrequency\*q +This optional entry specifies the maximum dot clock, in kHz, that is supported +by the monitor. +.TP 7 +.BI "Option " "\*qIgnore\*q " \*qbool\*q +This optional entry specifies that the monitor should be ignored entirely, +and not reported through RandR. This is useful if the hardware reports the +presence of outputs that don't exist. +(RandR 1.2-supporting drivers only) +.TP 7 +.BI "Option " "\*qRotate\*q " \*qrotation\*q +This optional entry specifies the initial rotation of the given monitor. +Valid values for rotation are \*qnormal\*q, \*qleft\*q, \*qright\*q, and +\*qinverted\*q. +(RandR 1.2-supporting drivers only) + +.SH "MODES SECTION" +The config file may have multiple +.B Modes +sections, or none. +These sections provide a way of defining sets of video modes independently +of the +.B Monitor +sections. +.B Monitor +sections may include the definitions provided in these sections by +using the +.B UseModes +keyword. +In most cases the +.B Modes +sections are not necessary because the built\-in set of VESA standard modes +will be sufficient. +.PP +.B Modes +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qModes\*q" +.BI " Identifier \*q" name \*q +.I " entries" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The +.B Identifier +entry specifies the unique name for this set of mode descriptions. +The other entries permitted in +.B Modes +sections are the +.B Mode +and +.B ModeLine +entries that are described above in the +.B Monitor +section. +.SH "SCREEN SECTION" +The config file may have multiple +.B Screen +sections. +There must be at least one, for the \(lqscreen\(rq being used. +A \(lqscreen\(rq represents the binding of a graphics device +.RB ( Device +section) and a monitor +.RB ( Monitor +section). +A +.B Screen +section is considered \(lqactive\(rq if it is referenced by an active +.B ServerLayout +section or by the +.B \-screen +command line option. +If neither of those is present, the first +.B Screen +section found in the config file is considered the active one. +.PP +.B Screen +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qScreen\*q" +.BI " Identifier \*q" name \*q +.BI " Device \*q" devid \*q +.BI " Monitor \*q" monid \*q +.I " entries" +.I " ..." +.BI " SubSection \*qDisplay\*q" +.I " entries" +.I " ... +.B " EndSubSection" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The +.B Identifier +and +.B Device +entries are mandatory. +All others are optional. +.PP +The +.B Identifier +entry specifies the unique name for this screen. +The +.B Screen +section provides information specific to the whole screen, including +screen\-specific +.BR Options . +In multi\-head configurations, there will be multiple active +.B Screen +sections, one for each head. +The entries available +for this section are: +.TP 7 +.BI "Device \*q" device\-id \*q +This mandatory entry specifies the +.B Device +section to be used for this screen. +This is what ties a specific graphics card to a screen. +The +.I device\-id +must match the +.B Identifier +of a +.B Device +section in the config file. +.TP 7 +.BI "Monitor \*q" monitor\-id \*q +specifies which monitor description is to be used for this screen. +If a +.B Monitor +name is not specified, a default configuration is used. +Currently the default configuration may not function as expected on all +platforms. +.TP 7 +.BI "VideoAdaptor \*q" xv\-id \*q +specifies an optional Xv video adaptor description to be used with this +screen. +.TP 7 +.BI "DefaultDepth " depth +specifies which color depth the server should use by default. +The +.B \-depth +command line option can be used to override this. +If neither is specified, the default depth is driver\-specific, but in most +cases is 8. +.TP 7 +.BI "DefaultFbBpp " bpp +specifies which framebuffer layout to use by default. +The +.B \-fbbpp +command line option can be used to override this. +In most cases the driver will chose the best default value for this. +The only case where there is even a choice in this value is for depth 24, +where some hardware supports both a packed 24 bit framebuffer layout and a +sparse 32 bit framebuffer layout. +.TP 7 +.B Options +Various +.B Option +flags may be specified in the +.B Screen +section. +Some are driver\-specific and are described in the driver documentation. +Others are driver\-independent, and will eventually be described here. +.\" XXX These should really be in an xaa man page. +.TP 7 +.BI "Option \*qAccel\*q" +Enables XAA (X Acceleration Architecture), a mechanism that makes video cards' +2D hardware acceleration available to the __xservername__ server. +This option is on by default, but it may be necessary to turn it off if +there are bugs in the driver. +There are many options to disable specific accelerated operations, listed +below. +Note that disabling an operation will have no effect if the operation is +not accelerated (whether due to lack of support in the hardware or in the +driver). +.TP 7 +.BI "Option \*qInitPrimary\*q \*q" boolean \*q +Use the Int10 module to initialize the primary graphics card. +Normally, only secondary cards are soft-booted using the Int10 module, as the +primary card has already been initialized by the BIOS at boot time. +Default: false. +.TP 7 +.BI "Option \*qNoInt10\*q \*q" boolean \*q +Disables the Int10 module, a module that uses the int10 call to the BIOS +of the graphics card to initialize it. +Default: false. +.TP 7 +.BI "Option \*qNoMTRR\*q" +Disables MTRR (Memory Type Range Register) support, a feature of modern +processors which can improve video performance by a factor of up to 2.5. +Some hardware has buggy MTRR support, and some video drivers have been +known to exhibit problems when MTRR's are used. +.TP 7 +.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q" +Disables accelerated rectangular expansion blits from source patterns +stored in system memory (using a memory\-mapped aperture). +.TP 7 +.BI "Option \*qXaaNoColor8x8PatternFillRect\*q" +Disables accelerated fills of a rectangular region with a full\-color +pattern. +.TP 7 +.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q" +Disables accelerated fills of a trapezoidal region with a full\-color +pattern. +.TP 7 +.BI "Option \*qXaaNoDashedBresenhamLine\*q" +Disables accelerated dashed Bresenham line draws. +.TP 7 +.BI "Option \*qXaaNoDashedTwoPointLine\*q" +Disables accelerated dashed line draws between two arbitrary points. +.TP 7 +.BI "Option \*qXaaNoImageWriteRect\*q" +Disables accelerated transfers of full\-color rectangular patterns from +system memory to video memory (using a memory\-mapped aperture). +.TP 7 +.BI "Option \*qXaaNoMono8x8PatternFillRect\*q" +Disables accelerated fills of a rectangular region with a monochrome +pattern. +.TP 7 +.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q" +Disables accelerated fills of a trapezoidal region with a monochrome +pattern. +.TP 7 +.BI "Option \*qXaaNoOffscreenPixmaps\*q" +Disables accelerated draws into pixmaps stored in offscreen video memory. +.TP 7 +.BI "Option \*qXaaNoPixmapCache\*q" +Disables caching of patterns in offscreen video memory. +.TP 7 +.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q" +Disables accelerated rectangular expansion blits from source patterns +stored in system memory (one scan line at a time). +.TP 7 +.BI "Option \*qXaaNoScanlineImageWriteRect\*q" +Disables accelerated transfers of full\-color rectangular patterns from +system memory to video memory (one scan line at a time). +.TP 7 +.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q" +Disables accelerated rectangular expansion blits from source patterns +stored in offscreen video memory. +.TP 7 +.BI "Option \*qXaaNoScreenToScreenCopy\*q" +Disables accelerated copies of rectangular regions from one part of +video memory to another part of video memory. +.TP 7 +.BI "Option \*qXaaNoSolidBresenhamLine\*q" +Disables accelerated solid Bresenham line draws. +.TP 7 +.BI "Option \*qXaaNoSolidFillRect\*q" +Disables accelerated solid\-color fills of rectangles. +.TP 7 +.BI "Option \*qXaaNoSolidFillTrap\*q" +Disables accelerated solid\-color fills of Bresenham trapezoids. +.TP 7 +.BI "Option \*qXaaNoSolidHorVertLine\*q" +Disables accelerated solid horizontal and vertical line draws. +.TP 7 +.BI "Option \*qXaaNoSolidTwoPointLine\*q" +Disables accelerated solid line draws between two arbitrary points. +.PP +Each +.B Screen +section may optionally contain one or more +.B Display +subsections. +Those subsections provide depth/fbbpp specific configuration information, +and the one chosen depends on the depth and/or fbbpp that is being used for +the screen. +The +.B Display +subsection format is described in the section below. + +.SH "DISPLAY SUBSECTION" +Each +.B Screen +section may have multiple +.B Display +subsections. +The \(lqactive\(rq +.B Display +subsection is the first that matches the depth and/or fbbpp values being +used, or failing that, the first that has neither a depth or fbbpp value +specified. +The +.B Display +subsections are optional. +When there isn't one that matches the depth and/or fbbpp values being used, +all the parameters that can be specified here fall back to their defaults. +.PP +.B Display +subsections have the following format: +.PP +.RS 4 +.nf +.B " SubSection \*qDisplay\*q" +.BI " Depth " depth +.I " entries" +.I " ..." +.B " EndSubSection" +.fi +.RE +.TP 7 +.BI "Depth " depth +This entry specifies what colour depth the +.B Display +subsection is to be used for. +This entry is usually specified, but it may be omitted to create a match\-all +.B Display +subsection or when wishing to match only against the +.B FbBpp +parameter. +The range of +.I depth +values that are allowed depends on the driver. +Most drivers support 8, 15, 16 and 24. +Some also support 1 and/or 4, and some may support other values (like 30). +Note: +.I depth +means the number of bits in a pixel that are actually used to determine +the pixel colour. +32 is not a valid +.I depth +value. +Most hardware that uses 32 bits per pixel only uses 24 of them to hold the +colour information, which means that the colour depth is 24, not 32. +.TP 7 +.BI "FbBpp " bpp +This entry specifies the framebuffer format this +.B Display +subsection is to be used for. +This entry is only needed when providing depth 24 configurations that allow +a choice between a 24 bpp packed framebuffer format and a 32bpp sparse +framebuffer format. +In most cases this entry should not be used. +.TP 7 +.BI "Weight " "red\-weight green\-weight blue\-weight" +This optional entry specifies the relative RGB weighting to be used +for a screen is being used at depth 16 for drivers that allow multiple +formats. +This may also be specified from the command line with the +.B \-weight +option (see +.BR __xservername__(__appmansuffix__)). +.TP 7 +.BI "Virtual " "xdim ydim" +This optional entry specifies the virtual screen resolution to be used. +.I xdim +must be a multiple of either 8 or 16 for most drivers, and a multiple +of 32 when running in monochrome mode. +The given value will be rounded down if this is not the case. +Video modes which are too large for the specified virtual size will be +rejected. +If this entry is not present, the virtual screen resolution will be set to +accommodate all the valid video modes given in the +.B Modes +entry. +Some drivers/hardware combinations do not support virtual screens. +Refer to the appropriate driver\-specific documentation for details. +.TP 7 +.BI "ViewPort " "x0 y0" +This optional entry sets the upper left corner of the initial display. +This is only relevant when the virtual screen resolution is different +from the resolution of the initial video mode. +If this entry is not given, then the initial display will be centered in +the virtual display area. +.TP 7 +.BI "Modes \*q" mode\-name \*q " ..." +This optional entry specifies the list of video modes to use. +Each +.I mode\-name +specified must be in double quotes. +They must correspond to those specified or referenced in the appropriate +.B Monitor +section (including implicitly referenced built\-in VESA standard modes). +The server will delete modes from this list which don't satisfy various +requirements. +The first valid mode in this list will be the default display mode for +startup. +The list of valid modes is converted internally into a circular list. +It is possible to switch to the next mode with +.B Ctrl+Alt+Keypad\-Plus +and to the previous mode with +.BR Ctrl+Alt+Keypad\-Minus . +When this entry is omitted, the valid modes referenced by the appropriate +.B Monitor +section will be used. If the +.B Monitor +section contains no modes, then the selection will be taken from the +built-in VESA standard modes. +.TP 7 +.BI "Visual \*q" visual\-name \*q +This optional entry sets the default root visual type. +This may also be specified from the command line (see the +.BR Xserver(__appmansuffix__) +man page). +The visual types available for depth 8 are (default is +.BR PseudoColor ): +.PP +.RS 11 +.nf +.B StaticGray +.B GrayScale +.B StaticColor +.B PseudoColor +.B TrueColor +.B DirectColor +.fi +.RE +.PP +.RS 7 +The visual type available for the depths 15, 16 and 24 are (default is +.BR TrueColor ): +.PP +.RS 4 +.nf +.B TrueColor +.B DirectColor +.fi +.RE +.PP +Not all drivers support +.B DirectColor +at these depths. +.PP +The visual types available for the depth 4 are (default is +.BR StaticColor ): +.PP +.RS 4 +.nf +.B StaticGray +.B GrayScale +.B StaticColor +.B PseudoColor +.fi +.RE +.PP +The visual type available for the depth 1 (monochrome) is +.BR StaticGray . +.RE +.TP 7 +.BI "Black " "red green blue" +This optional entry allows the \(lqblack\(rq colour to be specified. +This is only supported at depth 1. +The default is black. +.TP 7 +.BI "White " "red green blue" +This optional entry allows the \(lqwhite\(rq colour to be specified. +This is only supported at depth 1. +The default is white. +.TP 7 +.B Options +Option flags may be specified in the +.B Display +subsections. +These may include driver\-specific options and driver\-independent options. +The former are described in the driver\-specific documentation. +Some of the latter are described above in the section about the +.B Screen +section, and they may also be included here. +.SH "SERVERLAYOUT SECTION" +The config file may have multiple +.B ServerLayout +sections. +A \(lqserver layout\(rq represents the binding of one or more screens +.RB ( Screen +sections) and one or more input devices +.RB ( InputDevice +sections) to form a complete configuration. +In multi\-head configurations, it also specifies the relative layout of the +heads. +A +.B ServerLayout +section is considered \(lqactive\(rq if it is referenced by the +.B \-layout +command line option or by an +.B "Option \*qDefaultServerLayout\*q" +entry in the +.B ServerFlags +section (the former takes precedence over the latter). +If those options are not used, the first +.B ServerLayout +section found in the config file is considered the active one. +If no +.B ServerLayout +sections are present, the single active screen and two active (core) +input devices are selected as described in the relevant sections above. +.PP +.B ServerLayout +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qServerLayout\*q" +.BI " Identifier \*q" name \*q +.BI " Screen \*q" screen\-id \*q +.I " ..." +.BI " InputDevice \*q" idev\-id \*q +.I " ..." +.I " options" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +Each +.B ServerLayout +section must have an +.B Identifier +entry and at least one +.B Screen +entry. +.PP +The +.B Identifier +entry specifies the unique name for this server layout. +The +.B ServerLayout +section provides information specific to the whole session, including +session\-specific +.BR Options . +The +.B ServerFlags +options (described above) may be specified here, and ones given here +override those given in the +.B ServerFlags +section. +.PP +The entries that may be used in this section are described here. +.TP 7 +.BI "Screen " "screen\-num" " \*qscreen\-id\*q " "position\-information" +One of these entries must be given for each screen being used in +a session. +The +.I screen\-id +field is mandatory, and specifies the +.B Screen +section being referenced. +The +.I screen\-num +field is optional, and may be used to specify the screen number +in multi\-head configurations. +When this field is omitted, the screens will be numbered in the order that +they are listed in. +The numbering starts from 0, and must be consecutive. +The +.I position\-information +field describes the way multiple screens are positioned. +There are a number of different ways that this information can be provided: +.RS 7 +.TP 4 +.I "x y" +.TP 4 +.BI "Absolute " "x y" +These both specify that the upper left corner's coordinates are +.RI ( x , y ). +The +.B Absolute +keyword is optional. +Some older versions of XFree86 (4.2 and earlier) don't recognise the +.B Absolute +keyword, so it's safest to just specify the coordinates without it. +.TP 4 +.BI "RightOf \*q" screen\-id \*q +.TP 4 +.BI "LeftOf \*q" screen\-id \*q +.TP 4 +.BI "Above \*q" screen\-id \*q +.TP 4 +.BI "Below \*q" screen\-id \*q +.TP 4 +.BI "Relative \*q" screen\-id \*q " x y" +These give the screen's location relative to another screen. +The first four position the screen immediately to the right, left, above or +below the other screen. +When positioning to the right or left, the top edges are aligned. +When positioning above or below, the left edges are aligned. +The +.B Relative +form specifies the offset of the screen's origin (upper left corner) +relative to the origin of another screen. +.RE +.TP 7 +.BI "InputDevice \*q" idev\-id "\*q \*q" option \*q " ..." +One of these entries should be given for each input device being used in +a session. +Normally at least two are required, one each for the core pointer and +keyboard devices. +If either of those is missing, suitable +.B InputDevice +entries are searched for using the method described above in the +.B INPUTDEVICE +section. The +.I idev\-id +field is mandatory, and specifies the name of the +.B InputDevice +section being referenced. +Multiple +.I option +fields may be specified, each in double quotes. +The options permitted here are any that may also be given in the +.B InputDevice +sections. +Normally only session\-specific input device options would be used here. +The most commonly used options are: +.PP +.RS 11 +.nf +.B \*qCorePointer\*q +.B \*qCoreKeyboard\*q +.B \*qSendCoreEvents\*q +.fi +.RE +.PP +.RS 7 +and the first two should normally be used to indicate the core pointer +and core keyboard devices respectively. +.RE +.TP 7 +.B Options +In addition to the following, any option permitted in the +.B ServerFlags +section may also be specified here. +When the same option appears in both places, the value given here overrides +the one given in the +.B ServerFlags +section. +.TP 7 +.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q +Restrict device resets to the specified +.IR bus\-id . +See the +.B BusID +option (described in +.BR "DEVICE SECTION" , +above) for the format of the +.I bus\-id +parameter. +This option overrides +.BR SingleCard , +if specified. +At present, only PCI devices can be isolated in this manner. +.TP 7 +.BI "Option \*qSingleCard\*q \*q" boolean \*q +As +.BR IsolateDevice , +except that the bus ID of the first device in the layout is used. +.PP +Here is an example of a +.B ServerLayout +section for a dual headed configuration with two mice: +.PP +.RS 4 +.nf +.B "Section \*qServerLayout\*q" +.B " Identifier \*qLayout 1\*q" +.B " Screen \*qMGA 1\*q" +.B " Screen \*qMGA 2\*q RightOf \*qMGA 1\*q" +.B " InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q" +.B " InputDevice \*qMouse 1\*q \*qCorePointer\*q" +.B " InputDevice \*qMouse 2\*q \*qSendCoreEvents\*q" +.B " Option \*qBlankTime\*q \*q5\*q" +.B "EndSection" +.fi +.RE +.SH "DRI SECTION" +This optional section is used to provide some information for the +Direct Rendering Infrastructure. +Details about the format of this section can be found on-line at +.IR <http://dri.freedesktop.org/> . +.SH "VENDOR SECTION" +The optional +.B Vendor +section may be used to provide vendor\-specific configuration information. +Multiple +.B Vendor +sections may be present, and they may contain an +.B Identifier +entry and multiple +.B Option +flags. +The data therein is not used in this release. +.PP +.SH "SEE ALSO" +General: +.BR X (__miscmansuffix__), +.BR Xserver (__appmansuffix__), +.BR __xservername__ (__appmansuffix__), +.BR cvt (__appmansuffix__), +.BR gtf (__appmansuffix__). +.PP +.B "Not all modules or interfaces are available on all platforms." +.PP +Display drivers: +.BR apm (__drivermansuffix__), +.BR ati (__drivermansuffix__), +.BR chips (__drivermansuffix__), +.BR cirrus (__drivermansuffix__), +.BR cyrix (__drivermansuffix__), +.BR fbdev (__drivermansuffix__), +.BR glide (__drivermansuffix__), +.BR glint (__drivermansuffix__), +.BR i128 (__drivermansuffix__), +.BR i740 (__drivermansuffix__), +.BR imstt (__drivermansuffix__), +.BR intel (__drivermansuffix__), +.BR mga (__drivermansuffix__), +.BR neomagic (__drivermansuffix__), +.BR nv (__drivermansuffix__), +.BR openchrome (__drivermansuffix__), +.BR r128 (__drivermansuffix__), +.BR radeon (__drivermansuffix__), +.BR rendition (__drivermansuffix__), +.BR savage (__drivermansuffix__), +.BR s3virge (__drivermansuffix__), +.BR siliconmotion (__drivermansuffix__), +.BR sis (__drivermansuffix__), +.BR sisusb (__drivermansuffix__), +.BR sunbw2 (__drivermansuffix__), +.BR suncg14 (__drivermansuffix__), +.BR suncg3 (__drivermansuffix__), +.BR suncg6 (__drivermansuffix__), +.BR sunffb (__drivermansuffix__), +.BR sunleo (__drivermansuffix__), +.BR suntcx (__drivermansuffix__), +.BR tdfx (__drivermansuffix__), +.\" .BR tga (__drivermansuffix__), +.BR trident (__drivermansuffix__), +.BR tseng (__drivermansuffix__), +.BR vesa (__drivermansuffix__), +.BR vmware (__drivermansuffix__), +.BR voodoo (__drivermansuffix__), +.BR wsfb (__drivermansuffix__), +.BR xgi (__drivermansuffix__), +.BR xgixp (__drivermansuffix__). +.PP +Input drivers: +.BR acecad (__drivermansuffix__), +.BR citron (__drivermansuffix__), +.BR elographics (__drivermansuffix__), +.BR evdev (__drivermansuffix__), +.BR fpit (__drivermansuffix__), +.BR joystick (__drivermansuffix__), +.BR kbd (__drivermansuffix__), +.BR mousedrv (__drivermansuffix__), +.BR mutouch (__drivermansuffix__), +.BR penmount (__drivermansuffix__), +.BR synaptics (__drivermansuffix__), +.BR vmmouse (__drivermansuffix__), +.BR void (__drivermansuffix__), +.BR wacom (__drivermansuffix__). +.PP +Other modules and interfaces: +.BR exa (__drivermansuffix__), +.BR fbdevhw (__drivermansuffix__), +.\" .BR shadowfb (__drivermansuffix__), +.BR v4l (__drivermansuffix__). +.br +.SH AUTHORS +This manual page was largely rewritten by David Dawes +.IR <dawes@xfree86.org> . diff --git a/xorg-server/hw/xfree86/exa/Makefile.am b/xorg-server/hw/xfree86/exa/Makefile.am index da9b720d7..39f7a9057 100644 --- a/xorg-server/hw/xfree86/exa/Makefile.am +++ b/xorg-server/hw/xfree86/exa/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = man + module_LTLIBRARIES = libexa.la libexa_la_LDFLAGS = -avoid-version @@ -14,15 +16,3 @@ libexa_la_SOURCES = \ libexa_la_LIBADD = \ ../../../exa/libexa.la - -include $(top_srcdir)/cpprules.in - -drivermandir = $(DRIVER_MAN_DIR) -driverman_DATA = exa.$(DRIVER_MAN_SUFFIX) -CLEANFILES = $(driverman_DATA) exa.man - -exa.$(DRIVER_MAN_SUFFIX): exa.man - -$(AM_V_at)rm -f exa.$(DRIVER_MAN_SUFFIX) - $(AM_V_at)$(LN_S) exa.man exa.$(DRIVER_MAN_SUFFIX) - -EXTRA_DIST = exa.man.pre diff --git a/xorg-server/hw/xfree86/exa/man/Makefile.am b/xorg-server/hw/xfree86/exa/man/Makefile.am new file mode 100644 index 000000000..51da4fd50 --- /dev/null +++ b/xorg-server/hw/xfree86/exa/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +driverman_PRE = exa.man diff --git a/xorg-server/hw/xfree86/exa/exa.man.pre b/xorg-server/hw/xfree86/exa/man/exa.man index 5c953e256..30d01824d 100644 --- a/xorg-server/hw/xfree86/exa/exa.man.pre +++ b/xorg-server/hw/xfree86/exa/man/exa.man @@ -7,7 +7,7 @@ exa \- new 2D acceleration architecture for X.Org .B EXA provides a simple API for video drivers to implement for 2D acceleration. It is a module loaded by drivers, and is not intended to be loaded on its own. -See your driver's manual page for how to enable +See your driver's manual page for how to enable .BR EXA . .PP The @@ -25,7 +25,7 @@ the Render extension. Not related to the Composite extension. Default: No. Disables acceleration of uploading pixmap data to the framebuffer. Default: No. .TP .BI "Option \*qEXANoDownloadFromScreen\*q \*q" boolean \*q -Disables acceleration of downloading of pixmap data from the framebuffer. +Disables acceleration of downloading of pixmap data from the framebuffer. .B NOTE: Not usable with drivers which rely on DownloadFromScreen succeeding. Default: No. diff --git a/xorg-server/hw/xfree86/fbdevhw/Makefile.am b/xorg-server/hw/xfree86/fbdevhw/Makefile.am index 076b9741f..2a038905e 100644 --- a/xorg-server/hw/xfree86/fbdevhw/Makefile.am +++ b/xorg-server/hw/xfree86/fbdevhw/Makefile.am @@ -1,27 +1,19 @@ -module_LTLIBRARIES = libfbdevhw.la
-
-libfbdevhw_la_LDFLAGS = -avoid-version
-
-if FBDEVHW
-libfbdevhw_la_SOURCES = fbdevhw.c
-else
-libfbdevhw_la_SOURCES = fbdevhwstub.c
-endif
-
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c
-
-AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
-
-sdk_HEADERS = fbdevhw.h
-
-include $(top_srcdir)/cpprules.in
-
-drivermandir = $(DRIVER_MAN_DIR)
-driverman_DATA = fbdevhw.$(DRIVER_MAN_SUFFIX)
-CLEANFILES = $(driverman_DATA) fbdevhw.man
-
-fbdevhw.$(DRIVER_MAN_SUFFIX): fbdevhw.man
- -$(AM_V_at)rm -f fbdevhw.$(DRIVER_MAN_SUFFIX)
- $(AM_V_at)$(LN_S) fbdevhw.man fbdevhw.$(DRIVER_MAN_SUFFIX)
-
-EXTRA_DIST = fbpriv.h fbdevhw.man.pre README
+SUBDIRS = man + +module_LTLIBRARIES = libfbdevhw.la + +libfbdevhw_la_LDFLAGS = -avoid-version + +if FBDEVHW +libfbdevhw_la_SOURCES = fbdevhw.c +else +libfbdevhw_la_SOURCES = fbdevhwstub.c +endif + +INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c + +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) + +sdk_HEADERS = fbdevhw.h + +EXTRA_DIST = fbpriv.h README diff --git a/xorg-server/hw/xfree86/fbdevhw/man/Makefile.am b/xorg-server/hw/xfree86/fbdevhw/man/Makefile.am new file mode 100644 index 000000000..7f22a12b9 --- /dev/null +++ b/xorg-server/hw/xfree86/fbdevhw/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +driverman_PRE = fbdevhw.man diff --git a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.man.pre b/xorg-server/hw/xfree86/fbdevhw/man/fbdevhw.man index deeced860..fe5d1e17b 100644 --- a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.man.pre +++ b/xorg-server/hw/xfree86/fbdevhw/man/fbdevhw.man @@ -1,4 +1,4 @@ -.\" $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.man,v 1.1 2001/01/24 00:06:34 dawes Exp $ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.man,v 1.1 2001/01/24 00:06:34 dawes Exp $ .TH FBDEVHW __drivermansuffix__ __vendorversion__ .SH NAME fbdevhw \- os-specific submodule for framebuffer device access @@ -14,7 +14,7 @@ fbdev(__drivermansuffix__) is a non-accelerated driver which runs on top of the fbdevhw module. fbdevhw can be used by other drivers too, this is usually activated with `Option "UseFBDev"' in the device section. .SH "SEE ALSO" -__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), +__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__), fbdev(__drivermansuffix__) .SH AUTHORS diff --git a/xorg-server/hw/xfree86/utils/Makefile.am b/xorg-server/hw/xfree86/utils/Makefile.am index d27861b03..71f979048 100644 --- a/xorg-server/hw/xfree86/utils/Makefile.am +++ b/xorg-server/hw/xfree86/utils/Makefile.am @@ -1,3 +1,4 @@ SUBDIRS = \ gtf \ - cvt + cvt \ + man diff --git a/xorg-server/hw/xfree86/utils/cvt/Makefile.am b/xorg-server/hw/xfree86/utils/cvt/Makefile.am index 7f8364f86..4ebcedf39 100644 --- a/xorg-server/hw/xfree86/utils/cvt/Makefile.am +++ b/xorg-server/hw/xfree86/utils/cvt/Makefile.am @@ -1,42 +1,34 @@ -# Copyright (c) 2005, Oracle and/or its affiliates. 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 (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.
-#
-
-bin_PROGRAMS = cvt
-
-INCLUDES = $(XORG_INCS) \
- -I$(top_srcdir)/hw/xfree86/ddc \
- -I$(top_srcdir)/hw/xfree86/parser
-
-# gah
-cvt_SOURCES = cvt.c \
- $(top_srcdir)/hw/xfree86/modes/xf86cvt.c \
- $(top_srcdir)/os/xprintf.c
-
-cvt_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
-
-man1_MANS = cvt.man
-
-CLEANFILES = $(man1_MANS)
-
-include $(top_srcdir)/cpprules.in
-
-EXTRA_DIST = cvt.man.pre
+# Copyright (c) 2005, Oracle and/or its affiliates. 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 (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. +# + +bin_PROGRAMS = cvt + +INCLUDES = $(XORG_INCS) \ + -I$(top_srcdir)/hw/xfree86/ddc \ + -I$(top_srcdir)/hw/xfree86/parser + +# gah +cvt_SOURCES = cvt.c \ + $(top_srcdir)/hw/xfree86/modes/xf86cvt.c \ + $(top_srcdir)/os/xprintf.c + +cvt_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/xorg-server/hw/xfree86/utils/gtf/Makefile.am b/xorg-server/hw/xfree86/utils/gtf/Makefile.am index 0852541bd..f77bf608e 100644 --- a/xorg-server/hw/xfree86/utils/gtf/Makefile.am +++ b/xorg-server/hw/xfree86/utils/gtf/Makefile.am @@ -1,44 +1,27 @@ -# Copyright (c) 2005, Oracle and/or its affiliates. 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 (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.
-#
-
-bin_PROGRAMS = gtf
-
-gtf_SOURCES = gtf.c
-gtf_CFLAGS = $(XORG_CFLAGS)
-gtf_LDADD = -lm
-
-appmandir = $(APP_MAN_DIR)
-
-appman_PRE = gtf.man
-appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@)
-
-include $(top_srcdir)/cpprules.in
-
-EXTRA_DIST = gtf.man.pre
-BUILT_SOURCES = $(appman_PRE)
-CLEANFILES = $(appman_PRE) $(appman_DATA)
-
-SUFFIXES += .$(APP_MAN_SUFFIX) .man
-
-.man.$(APP_MAN_SUFFIX):
- -$(AM_V_at)rm -f $@
- $(AM_V_at)$(LN_S) $< $@
+# Copyright (c) 2005, Oracle and/or its affiliates. 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 (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. +# + +bin_PROGRAMS = gtf + +gtf_SOURCES = gtf.c +gtf_CFLAGS = $(XORG_CFLAGS) +gtf_LDADD = -lm diff --git a/xorg-server/hw/xfree86/utils/man/Makefile.am b/xorg-server/hw/xfree86/utils/man/Makefile.am new file mode 100644 index 000000000..7afc5bcca --- /dev/null +++ b/xorg-server/hw/xfree86/utils/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +appman_PRE = cvt.man gtf.man diff --git a/xorg-server/hw/xfree86/utils/cvt/cvt.man.pre b/xorg-server/hw/xfree86/utils/man/cvt.man index 8a292eed8..b380171ee 100644 --- a/xorg-server/hw/xfree86/utils/cvt/cvt.man.pre +++ b/xorg-server/hw/xfree86/utils/man/cvt.man @@ -13,7 +13,7 @@ cvt - calculate VESA CVT mode lines .I Cvt is a utility for calculating VESA Coordinated Video Timing modes. Given the desired horizontal and vertical resolutions, a modeline adhering to the CVT -standard is printed. This modeline can be included in __xservername__ +standard is printed. This modeline can be included in __xservername__ .B __xconfigfile__(__filemansuffix__) . diff --git a/xorg-server/hw/xfree86/utils/gtf/gtf.man.pre b/xorg-server/hw/xfree86/utils/man/gtf.man index 74ade74cb..74ade74cb 100644 --- a/xorg-server/hw/xfree86/utils/gtf/gtf.man.pre +++ b/xorg-server/hw/xfree86/utils/man/gtf.man diff --git a/xorg-server/hw/xfree86/xorgconf.cpp b/xorg-server/hw/xfree86/xorgconf.cpp index 8f0c83014..cd6d4a983 100644 --- a/xorg-server/hw/xfree86/xorgconf.cpp +++ b/xorg-server/hw/xfree86/xorgconf.cpp @@ -1,73 +1,73 @@ -XCOMM -XCOMM Copyright (c) 1994-1998 by The XFree86 Project, Inc. -XCOMM -XCOMM Permission is hereby granted, free of charge, to any person obtaining a -XCOMM copy of this software and associated documentation files (the "Software"), -XCOMM to deal in the Software without restriction, including without limitation -XCOMM the rights to use, copy, modify, merge, publish, distribute, sublicense, -XCOMM and/or sell copies of the Software, and to permit persons to whom the -XCOMM Software is furnished to do so, subject to the following conditions: -XCOMM -XCOMM The above copyright notice and this permission notice shall be included in -XCOMM all copies or substantial portions of the Software. -XCOMM -XCOMM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -XCOMM IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -XCOMM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -XCOMM THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -XCOMM WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -XCOMM OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -XCOMM SOFTWARE. -XCOMM -XCOMM Except as contained in this notice, the name of the XFree86 Project shall -XCOMM not be used in advertising or otherwise to promote the sale, use or other -XCOMM dealings in this Software without prior written authorization from the -XCOMM XFree86 Project. -XCOMM -XCOMM $XConsortium: XF86Conf.cpp /main/22 1996/10/23 11:43:51 kaleb $ - -XCOMM ********************************************************************** -XCOMM This is a sample configuration file only, intended to illustrate -XCOMM what a config file might look like. Refer to the __xconfigfile__(__filemansuffix__) -XCOMM man page for details about the format of this file. -XCOMM ********************************************************************** - -XCOMM The ordering of sections is not important in XFree86 4.0 and later, -XCOMM nor in any Xorg release. - -XCOMM ********************************************************************** -XCOMM Files section. This allows default font and module paths to be set -XCOMM ********************************************************************** +# +# Copyright (c) 1994-1998 by The XFree86 Project, Inc. +# +# 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 +# THE XFREE86 PROJECT 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. +# +# Except as contained in this notice, the name of the XFree86 Project shall +# not be used in advertising or otherwise to promote the sale, use or other +# dealings in this Software without prior written authorization from the +# XFree86 Project. +# +# $XConsortium: XF86Conf.cpp /main/22 1996/10/23 11:43:51 kaleb $ + +# ********************************************************************** +# This is a sample configuration file only, intended to illustrate +# what a config file might look like. Refer to the xorg.conf(__filemansuffix__) +# man page for details about the format of this file. +# ********************************************************************** + +# The ordering of sections is not important in XFree86 4.0 and later, +# nor in any Xorg release. + +# ********************************************************************** +# Files section. This allows default font and module paths to be set +# ********************************************************************** Section "Files" -XCOMM Multiple FontPath entries are allowed (which are concatenated together), -XCOMM as well as specifying multiple comma-separated entries in one FontPath -XCOMM command (or a combination of both methods). -XCOMM The default path is shown here. +# Multiple FontPath entries are allowed (which are concatenated together), +# as well as specifying multiple comma-separated entries in one FontPath +# command (or a combination of both methods). +# The default path is shown here. -XCOMM FontPath DEFAULTFONTPATH +# FontPath DEFAULTFONTPATH -XCOMM ModulePath can be used to set a search path for the X server modules. -XCOMM The default path is shown here. +# ModulePath can be used to set a search path for the X server modules. +# The default path is shown here. -XCOMM ModulePath MODULEPATH +# ModulePath MODULEPATH EndSection -XCOMM ********************************************************************** -XCOMM Module section -- this is an optional section which is used to specify -XCOMM which run-time loadable modules to load when the X server starts up. -XCOMM ********************************************************************** +# ********************************************************************** +# Module section -- this is an optional section which is used to specify +# which run-time loadable modules to load when the X server starts up. +# ********************************************************************** Section "Module" -XCOMM This loads the DBE extension module. +# This loads the DBE extension module. Load "dbe" -XCOMM This loads the miscellaneous extensions module, and disables -XCOMM initialisation of the XFree86-DGA extension within that module. +# This loads the miscellaneous extensions module, and disables +# initialisation of the XFree86-DGA extension within that module. SubSection "extmod" Option "omit xfree86-dga" @@ -76,53 +76,53 @@ XCOMM initialisation of the XFree86-DGA extension within that module. EndSection -XCOMM ********************************************************************** -XCOMM Server flags section. This contains various server-wide Options. -XCOMM ********************************************************************** +# ********************************************************************** +# Server flags section. This contains various server-wide Options. +# ********************************************************************** Section "ServerFlags" -XCOMM Uncomment this to cause a core dump at the spot where a signal is -XCOMM received. This may leave the console in an unusable state, but may -XCOMM provide a better stack trace in the core dump to aid in debugging +# Uncomment this to cause a core dump at the spot where a signal is +# received. This may leave the console in an unusable state, but may +# provide a better stack trace in the core dump to aid in debugging -XCOMM Option "NoTrapSignals" +# Option "NoTrapSignals" -XCOMM Uncomment this to disable the <Ctrl><Alt><Fn> VT switch sequence -XCOMM (where n is 1 through 12). This allows clients to receive these key -XCOMM events. +# Uncomment this to disable the <Ctrl><Alt><Fn> VT switch sequence +# (where n is 1 through 12). This allows clients to receive these key +# events. -XCOMM Option "DontVTSwitch" +# Option "DontVTSwitch" -XCOMM Uncomment this to disable the <Ctrl><Alt><BS> server abort sequence -XCOMM This allows clients to receive this key event. +# Uncomment this to disable the <Ctrl><Alt><BS> server abort sequence +# This allows clients to receive this key event. -XCOMM Option "DontZap" "false" +# Option "DontZap" "false" -XCOMM Uncomment this to disable the <Ctrl><Alt><KP_+>/<KP_-> mode switching -XCOMM sequences. This allows clients to receive these key events. +# Uncomment this to disable the <Ctrl><Alt><KP_+>/<KP_-> mode switching +# sequences. This allows clients to receive these key events. -XCOMM Option "DontZoom" +# Option "DontZoom" -XCOMM Uncomment this to disable tuning with the xvidtune client. With -XCOMM it the client can still run and fetch card and monitor attributes, -XCOMM but it will not be allowed to change them. If it tries it will -XCOMM receive a protocol error. +# Uncomment this to disable tuning with the xvidtune client. With +# it the client can still run and fetch card and monitor attributes, +# but it will not be allowed to change them. If it tries it will +# receive a protocol error. -XCOMM Option "DisableVidModeExtension" +# Option "DisableVidModeExtension" -XCOMM Uncomment this to enable the use of a non-local xvidtune client. +# Uncomment this to enable the use of a non-local xvidtune client. -XCOMM Option "AllowNonLocalXvidtune" +# Option "AllowNonLocalXvidtune" -XCOMM Set the basic blanking screen saver timeout. +# Set the basic blanking screen saver timeout. Option "BlankTime" "10" # 10 minutes -XCOMM Set the DPMS timeouts. These are set here because they are global -XCOMM rather than screen-specific. These settings alone don't enable DPMS. -XCOMM It is enabled per-screen (or per-monitor), and even then only when -XCOMM the driver supports it. +# Set the DPMS timeouts. These are set here because they are global +# rather than screen-specific. These settings alone don't enable DPMS. +# It is enabled per-screen (or per-monitor), and even then only when +# the driver supports it. Option "StandbyTime" "10" # 10 minutes Option "SuspendTime" "10" # 10 minutes @@ -130,115 +130,115 @@ XCOMM the driver supports it. EndSection -XCOMM ********************************************************************** -XCOMM Input devices -XCOMM ********************************************************************** +# ********************************************************************** +# Input devices +# ********************************************************************** -XCOMM ********************************************************************** -XCOMM Core keyboard's InputDevice section -XCOMM ********************************************************************** +# ********************************************************************** +# Core keyboard's InputDevice section +# ********************************************************************** Section "InputDevice" Identifier "Keyboard1" Driver "kbd" -XCOMM Set the keyboard auto repeat parameters. Not all platforms implement -XCOMM this. +# Set the keyboard auto repeat parameters. Not all platforms implement +# this. Option "AutoRepeat" "500 5" -XCOMM Specifiy which keyboard LEDs can be user-controlled (eg, with xset(1)). - -XCOMM Option "Xleds" "1 2 3" - -XCOMM To customise the XKB settings to suit your keyboard, modify the -XCOMM lines below (which are the defaults). For example, for a European -XCOMM keyboard, you will probably want to use one of: -XCOMM -XCOMM Option "XkbModel" "pc102" -XCOMM Option "XkbModel" "pc105" -XCOMM -XCOMM If you have a Microsoft Natural keyboard, you can use: -XCOMM -XCOMM Option "XkbModel" "microsoft" -XCOMM -XCOMM If you have a US "windows" keyboard you will want: -XCOMM -XCOMM Option "XkbModel" "pc104" -XCOMM -XCOMM Then to change the language, change the Layout setting. -XCOMM For example, a german layout can be obtained with: -XCOMM -XCOMM Option "XkbLayout" "de" -XCOMM -XCOMM or: -XCOMM -XCOMM Option "XkbLayout" "de" -XCOMM Option "XkbVariant" "nodeadkeys" -XCOMM -XCOMM If you'd like to switch the positions of your capslock and -XCOMM control keys, use: -XCOMM -XCOMM Option "XkbOptions" "ctrl:swapcaps" - - -XCOMM These are the default XKB settings for xorg -XCOMM -XCOMM Option "XkbRules" "xorg" -XCOMM Option "XkbModel" "pc105" -XCOMM Option "XkbLayout" "us" -XCOMM Option "XkbVariant" "" -XCOMM Option "XkbOptions" "" +# Specifiy which keyboard LEDs can be user-controlled (eg, with xset(1)). + +# Option "Xleds" "1 2 3" + +# To customise the XKB settings to suit your keyboard, modify the +# lines below (which are the defaults). For example, for a European +# keyboard, you will probably want to use one of: +# +# Option "XkbModel" "pc102" +# Option "XkbModel" "pc105" +# +# If you have a Microsoft Natural keyboard, you can use: +# +# Option "XkbModel" "microsoft" +# +# If you have a US "windows" keyboard you will want: +# +# Option "XkbModel" "pc104" +# +# Then to change the language, change the Layout setting. +# For example, a german layout can be obtained with: +# +# Option "XkbLayout" "de" +# +# or: +# +# Option "XkbLayout" "de" +# Option "XkbVariant" "nodeadkeys" +# +# If you'd like to switch the positions of your capslock and +# control keys, use: +# +# Option "XkbOptions" "ctrl:swapcaps" + + +# These are the default XKB settings for xorg +# +# Option "XkbRules" "xorg" +# Option "XkbModel" "pc105" +# Option "XkbLayout" "us" +# Option "XkbVariant" "" +# Option "XkbOptions" "" EndSection -XCOMM ********************************************************************** -XCOMM Core Pointer's InputDevice section -XCOMM ********************************************************************** +# ********************************************************************** +# Core Pointer's InputDevice section +# ********************************************************************** Section "InputDevice" -XCOMM Identifier and driver +# Identifier and driver Identifier "Mouse1" Driver "mouse" -XCOMM The mouse protocol and device. The device is normally set to /dev/mouse, -XCOMM which is usually a symbolic link to the real device. +# The mouse protocol and device. The device is normally set to /dev/mouse, +# which is usually a symbolic link to the real device. Option "Protocol" "Microsoft" Option "Device" "/dev/mouse" -XCOMM On platforms where PnP mouse detection is supported the following -XCOMM protocol setting can be used when using a newer PnP mouse: +# On platforms where PnP mouse detection is supported the following +# protocol setting can be used when using a newer PnP mouse: -XCOMM Option "Protocol" "Auto" +# Option "Protocol" "Auto" -XCOMM When using mouse connected to a PS/2 port (aka "MousePort"), set the -XCOMM the protocol as follows. On some platforms some other settings may -XCOMM be available. +# When using mouse connected to a PS/2 port (aka "MousePort"), set the +# the protocol as follows. On some platforms some other settings may +# be available. -XCOMM Option "Protocol" "PS/2" +# Option "Protocol" "PS/2" -XCOMM Baudrate and SampleRate are only for some older Logitech mice. In -XCOMM almost every case these lines should be omitted. +# Baudrate and SampleRate are only for some older Logitech mice. In +# almost every case these lines should be omitted. -XCOMM Option "BaudRate" "9600" -XCOMM Option "SampleRate" "150" +# Option "BaudRate" "9600" +# Option "SampleRate" "150" -XCOMM Emulate3Buttons is an option for 2-button mice -XCOMM Emulate3Timeout is the timeout in milliseconds (default is 50ms) +# Emulate3Buttons is an option for 2-button mice +# Emulate3Timeout is the timeout in milliseconds (default is 50ms) -XCOMM Option "Emulate3Buttons" -XCOMM Option "Emulate3Timeout" "50" +# Option "Emulate3Buttons" +# Option "Emulate3Timeout" "50" -XCOMM ChordMiddle is an option for some 3-button Logitech mice, or any -XCOMM 3-button mouse where the middle button generates left+right button -XCOMM events. +# ChordMiddle is an option for some 3-button Logitech mice, or any +# 3-button mouse where the middle button generates left+right button +# events. -XCOMM Option "ChordMiddle" +# Option "ChordMiddle" EndSection @@ -249,91 +249,91 @@ Section "InputDevice" Option "Device" "/dev/mouse2" EndSection -XCOMM Some examples of extended input devices - -XCOMM Section "InputDevice" -XCOMM Identifier "spaceball" -XCOMM Driver "magellan" -XCOMM Option "Device" "/dev/cua0" -XCOMM EndSection -XCOMM -XCOMM Section "InputDevice" -XCOMM Identifier "spaceball2" -XCOMM Driver "spaceorb" -XCOMM Option "Device" "/dev/cua0" -XCOMM EndSection -XCOMM -XCOMM Section "InputDevice" -XCOMM Identifier "touchscreen0" -XCOMM Driver "microtouch" -XCOMM Option "Device" "/dev/ttyS0" -XCOMM Option "MinX" "1412" -XCOMM Option "MaxX" "15184" -XCOMM Option "MinY" "15372" -XCOMM Option "MaxY" "1230" -XCOMM Option "ScreenNumber" "0" -XCOMM Option "ReportingMode" "Scaled" -XCOMM Option "ButtonNumber" "1" -XCOMM Option "SendCoreEvents" -XCOMM EndSection -XCOMM -XCOMM Section "InputDevice" -XCOMM Identifier "touchscreen1" -XCOMM Driver "elo2300" -XCOMM Option "Device" "/dev/ttyS0" -XCOMM Option "MinX" "231" -XCOMM Option "MaxX" "3868" -XCOMM Option "MinY" "3858" -XCOMM Option "MaxY" "272" -XCOMM Option "ScreenNumber" "0" -XCOMM Option "ReportingMode" "Scaled" -XCOMM Option "ButtonThreshold" "17" -XCOMM Option "ButtonNumber" "1" -XCOMM Option "SendCoreEvents" -XCOMM EndSection - -XCOMM ********************************************************************** -XCOMM Monitor section -XCOMM ********************************************************************** - -XCOMM Any number of monitor sections may be present +# Some examples of extended input devices + +# Section "InputDevice" +# Identifier "spaceball" +# Driver "magellan" +# Option "Device" "/dev/cua0" +# EndSection +# +# Section "InputDevice" +# Identifier "spaceball2" +# Driver "spaceorb" +# Option "Device" "/dev/cua0" +# EndSection +# +# Section "InputDevice" +# Identifier "touchscreen0" +# Driver "microtouch" +# Option "Device" "/dev/ttyS0" +# Option "MinX" "1412" +# Option "MaxX" "15184" +# Option "MinY" "15372" +# Option "MaxY" "1230" +# Option "ScreenNumber" "0" +# Option "ReportingMode" "Scaled" +# Option "ButtonNumber" "1" +# Option "SendCoreEvents" +# EndSection +# +# Section "InputDevice" +# Identifier "touchscreen1" +# Driver "elo2300" +# Option "Device" "/dev/ttyS0" +# Option "MinX" "231" +# Option "MaxX" "3868" +# Option "MinY" "3858" +# Option "MaxY" "272" +# Option "ScreenNumber" "0" +# Option "ReportingMode" "Scaled" +# Option "ButtonThreshold" "17" +# Option "ButtonNumber" "1" +# Option "SendCoreEvents" +# EndSection + +# ********************************************************************** +# Monitor section +# ********************************************************************** + +# Any number of monitor sections may be present Section "Monitor" -XCOMM The identifier line must be present. +# The identifier line must be present. Identifier "Generic Monitor" -XCOMM HorizSync is in kHz unless units are specified. -XCOMM HorizSync may be a comma separated list of discrete values, or a -XCOMM comma separated list of ranges of values. -XCOMM NOTE: THE VALUES HERE ARE EXAMPLES ONLY. REFER TO YOUR MONITOR'S -XCOMM USER MANUAL FOR THE CORRECT NUMBERS. +# HorizSync is in kHz unless units are specified. +# HorizSync may be a comma separated list of discrete values, or a +# comma separated list of ranges of values. +# NOTE: THE VALUES HERE ARE EXAMPLES ONLY. REFER TO YOUR MONITOR'S +# USER MANUAL FOR THE CORRECT NUMBERS. -XCOMM HorizSync 31.5 # typical for a single frequency fixed-sync monitor -XCOMM HorizSync 30-64 # multisync -XCOMM HorizSync 31.5, 35.2 # multiple fixed sync frequencies -XCOMM HorizSync 15-25, 30-50 # multiple ranges of sync frequencies +# HorizSync 31.5 # typical for a single frequency fixed-sync monitor +# HorizSync 30-64 # multisync +# HorizSync 31.5, 35.2 # multiple fixed sync frequencies +# HorizSync 15-25, 30-50 # multiple ranges of sync frequencies -XCOMM VertRefresh is in Hz unless units are specified. -XCOMM VertRefresh may be a comma separated list of discrete values, or a -XCOMM comma separated list of ranges of values. -XCOMM NOTE: THE VALUES HERE ARE EXAMPLES ONLY. REFER TO YOUR MONITOR'S -XCOMM USER MANUAL FOR THE CORRECT NUMBERS. +# VertRefresh is in Hz unless units are specified. +# VertRefresh may be a comma separated list of discrete values, or a +# comma separated list of ranges of values. +# NOTE: THE VALUES HERE ARE EXAMPLES ONLY. REFER TO YOUR MONITOR'S +# USER MANUAL FOR THE CORRECT NUMBERS. -XCOMM VertRefresh 60 # typical for a single frequency fixed-sync monitor +# VertRefresh 60 # typical for a single frequency fixed-sync monitor -XCOMM VertRefresh 50-100 # multisync -XCOMM VertRefresh 60, 65 # multiple fixed sync frequencies -XCOMM VertRefresh 40-50, 80-100 # multiple ranges of sync frequencies +# VertRefresh 50-100 # multisync +# VertRefresh 60, 65 # multiple fixed sync frequencies +# VertRefresh 40-50, 80-100 # multiple ranges of sync frequencies -XCOMM Modes can be specified in two formats. A compact one-line format, or -XCOMM a multi-line format. +# Modes can be specified in two formats. A compact one-line format, or +# a multi-line format. -XCOMM A generic VGA 640x480 mode (hsync = 31.5kHz, refresh = 60Hz) -XCOMM These two are equivalent +# A generic VGA 640x480 mode (hsync = 31.5kHz, refresh = 60Hz) +# These two are equivalent -XCOMM ModeLine "640x480" 25.175 640 664 760 800 480 491 493 525 +# ModeLine "640x480" 25.175 640 664 760 800 480 491 493 525 Mode "640x480" DotClock 25.175 @@ -341,75 +341,75 @@ XCOMM ModeLine "640x480" 25.175 640 664 760 800 480 491 493 525 VTimings 480 491 493 525 EndMode -XCOMM These two are equivalent +# These two are equivalent -XCOMM ModeLine "1024x768i" 45 1024 1048 1208 1264 768 776 784 817 Interlace +# ModeLine "1024x768i" 45 1024 1048 1208 1264 768 776 784 817 Interlace -XCOMM Mode "1024x768i" -XCOMM DotClock 45 -XCOMM HTimings 1024 1048 1208 1264 -XCOMM VTimings 768 776 784 817 -XCOMM Flags "Interlace" -XCOMM EndMode +# Mode "1024x768i" +# DotClock 45 +# HTimings 1024 1048 1208 1264 +# VTimings 768 776 784 817 +# Flags "Interlace" +# EndMode -XCOMM If a monitor has DPMS support, that can be indicated here. This will -XCOMM enable DPMS when the monitor is used with drivers that support it. +# If a monitor has DPMS support, that can be indicated here. This will +# enable DPMS when the monitor is used with drivers that support it. -XCOMM Option "dpms" +# Option "dpms" -XCOMM If a monitor requires that the sync signals be superimposed on the -XCOMM green signal, the following option will enable this when used with -XCOMM drivers that support it. Only a relatively small range of hardware -XCOMM (and drivers) actually support this. +# If a monitor requires that the sync signals be superimposed on the +# green signal, the following option will enable this when used with +# drivers that support it. Only a relatively small range of hardware +# (and drivers) actually support this. -XCOMM Option "sync on green" +# Option "sync on green" EndSection -XCOMM ********************************************************************** -XCOMM Graphics device section -XCOMM ********************************************************************** +# ********************************************************************** +# Graphics device section +# ********************************************************************** -XCOMM Any number of graphics device sections may be present +# Any number of graphics device sections may be present Section "Device" -XCOMM The Identifier must be present. +# The Identifier must be present. Identifier "Generic VESA" -XCOMM The Driver line must be present. When using run-time loadable driver -XCOMM modules, this line instructs the server to load the specified driver -XCOMM module. Even when not using loadable driver modules, this line -XCOMM indicates which driver should interpret the information in this section. +# The Driver line must be present. When using run-time loadable driver +# modules, this line instructs the server to load the specified driver +# module. Even when not using loadable driver modules, this line +# indicates which driver should interpret the information in this section. Driver "vesa" -XCOMM The chipset line is optional in most cases. It can be used to override -XCOMM the driver's chipset detection, and should not normally be specified. +# The chipset line is optional in most cases. It can be used to override +# the driver's chipset detection, and should not normally be specified. -XCOMM Chipset "generic" +# Chipset "generic" -XCOMM Various other lines can be specified to override the driver's automatic -XCOMM detection code. In most cases they are not needed. +# Various other lines can be specified to override the driver's automatic +# detection code. In most cases they are not needed. -XCOMM VideoRam 256 -XCOMM Clocks 25.2 28.3 +# VideoRam 256 +# Clocks 25.2 28.3 -XCOMM The BusID line is used to specify which of possibly multiple devices -XCOMM this section is intended for. When this line isn't present, a device -XCOMM section can only match up with the primary video device. For PCI -XCOMM devices a line like the following could be used. This line should not -XCOMM normally be included unless there is more than one video device -XCOMM intalled. +# The BusID line is used to specify which of possibly multiple devices +# this section is intended for. When this line isn't present, a device +# section can only match up with the primary video device. For PCI +# devices a line like the following could be used. This line should not +# normally be included unless there is more than one video device +# intalled. -XCOMM BusID "PCI:0:10:0" +# BusID "PCI:0:10:0" -XCOMM Various option lines can be added here as required. Some options -XCOMM are more appropriate in Screen sections, Display subsections or even -XCOMM Monitor sections. +# Various option lines can be added here as required. Some options +# are more appropriate in Screen sections, Display subsections or even +# Monitor sections. -XCOMM Option "hw cursor" "off" +# Option "hw cursor" "off" EndSection @@ -433,24 +433,24 @@ Section "Device" EndSection -XCOMM ********************************************************************** -XCOMM Screen sections. -XCOMM ********************************************************************** +# ********************************************************************** +# Screen sections. +# ********************************************************************** -XCOMM Any number of screen sections may be present. Each describes -XCOMM the configuration of a single screen. A single specific screen section -XCOMM may be specified from the X server command line with the "-screen" -XCOMM option. +# Any number of screen sections may be present. Each describes +# the configuration of a single screen. A single specific screen section +# may be specified from the X server command line with the "-screen" +# option. Section "Screen" -XCOMM The Identifier, Device and Monitor lines must be present +# The Identifier, Device and Monitor lines must be present Identifier "Screen 1" Device "Generic VESA" Monitor "Generic Monitor" -XCOMM The favoured Depth and/or Bpp may be specified here +# The favoured Depth and/or Bpp may be specified here DefaultDepth 8 @@ -480,7 +480,7 @@ Section "Screen" Monitor "Generic Monitor" Option "no accel" DefaultDepth 16 -XCOMM DefaultDepth 24 +# DefaultDepth 24 SubSection "Display" Depth 8 @@ -514,38 +514,38 @@ Section "Screen" EndSection -XCOMM ********************************************************************** -XCOMM ServerLayout sections. -XCOMM ********************************************************************** +# ********************************************************************** +# ServerLayout sections. +# ********************************************************************** -XCOMM Any number of ServerLayout sections may be present. Each describes -XCOMM the way multiple screens are organised. A specific ServerLayout -XCOMM section may be specified from the X server command line with the -XCOMM "-layout" option. In the absence of this, the first section is used. -XCOMM When now ServerLayout section is present, the first Screen section -XCOMM is used alone. +# Any number of ServerLayout sections may be present. Each describes +# the way multiple screens are organised. A specific ServerLayout +# section may be specified from the X server command line with the +# "-layout" option. In the absence of this, the first section is used. +# When now ServerLayout section is present, the first Screen section +# is used alone. Section "ServerLayout" -XCOMM The Identifier line must be present +# The Identifier line must be present Identifier "Main Layout" -XCOMM Each Screen line specifies a Screen section name, and optionally -XCOMM the relative position of other screens. The four names after -XCOMM primary screen name are the screens to the top, bottom, left and right -XCOMM of the primary screen. In this example, screen 2 is located to the -XCOMM right of screen 1. +# Each Screen line specifies a Screen section name, and optionally +# the relative position of other screens. The four names after +# primary screen name are the screens to the top, bottom, left and right +# of the primary screen. In this example, screen 2 is located to the +# right of screen 1. Screen "Screen MGA 1" "" "" "" "Screen MGA 2" Screen "Screen MGA 2" "" "" "Screen MGA 1" "" -XCOMM Each InputDevice line specifies an InputDevice section name and -XCOMM optionally some options to specify the way the device is to be -XCOMM used. Those options include "CorePointer", "CoreKeyboard" and -XCOMM "SendCoreEvents". In this example, "Mouse1" is the core pointer, -XCOMM and "Mouse2" is an extended input device that also generates core -XCOMM pointer events (i.e., both mice will move the standard pointer). +# Each InputDevice line specifies an InputDevice section name and +# optionally some options to specify the way the device is to be +# used. Those options include "CorePointer", "CoreKeyboard" and +# "SendCoreEvents". In this example, "Mouse1" is the core pointer, +# and "Mouse2" is an extended input device that also generates core +# pointer events (i.e., both mice will move the standard pointer). InputDevice "Mouse1" "CorePointer" InputDevice "Mouse2" "SendCoreEvents" diff --git a/xorg-server/hw/xnest/Makefile.am b/xorg-server/hw/xnest/Makefile.am index 666a0f0e6..c395b4dae 100644 --- a/xorg-server/hw/xnest/Makefile.am +++ b/xorg-server/hw/xnest/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = man + bin_PROGRAMS = Xnest noinst_LIBRARIES = libfbcmap.a @@ -59,34 +61,12 @@ Xnest_LDADD = $(XNEST_LIBS) $(XNEST_SYS_LIBS) $(XSERVER_SYS_LIBS) Xnest_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) EXTRA_DIST = icon \ - screensaver \ - Xnest.man.pre + screensaver # -UDPMSExtension for miinitext? can't put into # OS_DEFINES??? # EXT_DEFINES??? # ICONFIGFILES -- SpecialCObjectRule -# Man page -include $(top_srcdir)/cpprules.in - -appmandir = $(APP_MAN_DIR) - -appman_PRE = Xnest.man -appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) - -EXTRAMANDEFS = \ - -D__XCONFIGFILE__=$(__XCONFIGFILE__) \ - -D__XSERVERNAME__=$(XSERVERNAME) - -BUILT_SOURCES = $(appman_PRE) -CLEANFILES = $(appman_PRE) $(appman_DATA) - -SUFFIXES += .$(APP_MAN_SUFFIX) .man - -.man.$(APP_MAN_SUFFIX): - -$(AM_V_at)rm -f $@ - $(AM_V_at)$(LN_S) $< $@ - relink: $(AM_V_at)rm -f Xnest$(EXEEXT) && $(MAKE) Xnest$(EXEEXT) diff --git a/xorg-server/hw/xnest/man/Makefile.am b/xorg-server/hw/xnest/man/Makefile.am new file mode 100644 index 000000000..30b6370bc --- /dev/null +++ b/xorg-server/hw/xnest/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +appman_PRE = Xnest.man diff --git a/xorg-server/hw/xnest/Xnest.man.pre b/xorg-server/hw/xnest/man/Xnest.man index 024d88e82..024d88e82 100644 --- a/xorg-server/hw/xnest/Xnest.man.pre +++ b/xorg-server/hw/xnest/man/Xnest.man diff --git a/xorg-server/hw/xquartz/Makefile.am b/xorg-server/hw/xquartz/Makefile.am index 96b1fb0c5..61b04e0e1 100644 --- a/xorg-server/hw/xquartz/Makefile.am +++ b/xorg-server/hw/xquartz/Makefile.am @@ -14,9 +14,9 @@ if GLX GL_DIR = GL endif -SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup doc +SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup man -DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup doc +DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup man libXquartz_la_SOURCES = \ $(top_srcdir)/fb/fbcmap_mi.c \ diff --git a/xorg-server/hw/xquartz/bundle/cpprules.in b/xorg-server/hw/xquartz/bundle/cpprules.in index f32eafc06..92a987d92 100644 --- a/xorg-server/hw/xquartz/bundle/cpprules.in +++ b/xorg-server/hw/xquartz/bundle/cpprules.in @@ -13,25 +13,7 @@ CPP_SED_MAGIC = $(SED) -e '/^\# *[0-9][0-9]* *.*$$/d' \ -e '/XSLASHGLOB/s/XSLASHGLOB/\/\*/' \ -e '/\@\@$$/s/\@\@$$/\\/' -# Strings to replace in man pages -XORGRELSTRING = @PACKAGE_STRING@ - XORGMANNAME = X Version 11 - -MANDEFS = \ - -D__xorgversion__="\"$(XORGRELSTRING)\" \"$(XORGMANNAME)\"" \ - -D__appmansuffix__=$(APP_MAN_SUFFIX) \ - -D__filemansuffix__=$(FILE_MAN_SUFFIX) \ - -D__libmansuffix__=$(LIB_MAN_SUFFIX) \ - -D__miscmansuffix__=$(MISC_MAN_SUFFIX) \ - -D__XSERVERNAME__=Xorg -D__XCONFIGFILE__=xorg.conf \ - -D__xinitdir__=$(XINITDIR) \ - -D__bindir__=$(bindir) \ - -DSHELL_CMD=$(SHELL_CMD) $(ARCHMANDEFS) - -SUFFIXES = .$(APP_MAN_SUFFIX) .man .cpp +SUFFIXES = .cpp .cpp: - $(RAWCPP) $(RAWCPPFLAGS) $(CPP_FILES_FLAGS) < $< | $(CPP_SED_MAGIC) > $@ - -.man.$(APP_MAN_SUFFIX): - $(RAWCPP) $(RAWCPPFLAGS) $(MANDEFS) $(EXTRAMANDEFS) < $< | $(CPP_SED_MAGIC) > $@ + $(AM_V_GEN)$(RAWCPP) $(RAWCPPFLAGS) $(CPP_FILES_FLAGS) < $< | $(CPP_SED_MAGIC) > $@ diff --git a/xorg-server/hw/xquartz/doc/Makefile.am b/xorg-server/hw/xquartz/doc/Makefile.am deleted file mode 100644 index 6c68c845e..000000000 --- a/xorg-server/hw/xquartz/doc/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -appmandir = $(APP_MAN_DIR) -appman_PRE = Xquartz.man.pre -appman_PROCESSED = $(appman_PRE:man.pre=man) -appman_DATA = $(appman_PRE:man.pre=@APP_MAN_SUFFIX@) - -CLEANFILES = $(appman_PROCESSED) $(appman_DATA) - -include $(top_srcdir)/cpprules.in - -MANDEFS += -D__laucnd_id_prefix__=$(LAUNCHD_ID_PREFIX) - -.man.$(APP_MAN_SUFFIX): - $(AM_V_at)cp $< $@ - -EXTRA_DIST = \ - Xquartz.man.pre diff --git a/xorg-server/hw/xquartz/man/Makefile.am b/xorg-server/hw/xquartz/man/Makefile.am new file mode 100644 index 000000000..5a0cde7cc --- /dev/null +++ b/xorg-server/hw/xquartz/man/Makefile.am @@ -0,0 +1,2 @@ +include $(top_srcdir)/manpages.am +appman_PRE = Xquartz.man diff --git a/xorg-server/hw/xquartz/doc/Xquartz.man.pre b/xorg-server/hw/xquartz/man/Xquartz.man index 447194740..447194740 100644 --- a/xorg-server/hw/xquartz/doc/Xquartz.man.pre +++ b/xorg-server/hw/xquartz/man/Xquartz.man diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am index 6eed2bf16..f6a75df2c 100644 --- a/xorg-server/hw/xwin/Makefile.am +++ b/xorg-server/hw/xwin/Makefile.am @@ -1,224 +1,203 @@ -bin_PROGRAMS = XWin
-
-if XWIN_CLIPBOARD
-SRCS_CLIPBOARD = \
- winclipboardinit.c \
- winclipboardtextconv.c \
- winclipboardthread.c \
- winclipboardunicode.c \
- winclipboardwndproc.c \
- winclipboardwrappers.c \
- winclipboardxevents.c
-DEFS_CLIPBOARD = -DXWIN_CLIPBOARD
-endif
-
-if XWIN_GLX_WINDOWS
-GLX_DIR = glx
-DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS
-XWIN_GLX_LIBS = $(top_builddir)/hw/xwin/glx/libXwinGLX.la
-XWIN_GLX_LINK_FLAGS = -lopengl32
-endif
-
-if XWIN_MULTIWINDOW
-SRCS_MULTIWINDOW = \
- winmultiwindowshape.c \
- winmultiwindowwindow.c \
- winmultiwindowwm.c \
- winmultiwindowwndproc.c
-DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
-endif
-
-if XWIN_MULTIWINDOWEXTWM
-SRCS_MULTIWINDOWEXTWM = \
- winwin32rootless.c \
- winwin32rootlesswindow.c \
- winwin32rootlesswndproc.c \
- winwindowswm.c
-DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM
-MULTIWINDOWEXTWM_LIBS = $(top_builddir)/miext/rootless/librootless.la
-endif
-
-if XWIN_NATIVEGDI
-SRCS_NATIVEGDI = \
- winclip.c \
- winfillsp.c \
- winfont.c \
- wingc.c \
- wingetsp.c \
- winnativegdi.c \
- winpixmap.c \
- winpolyline.c \
- winrop.c \
- winsetsp.c
-DEFS_NATIVEGDI = -DXWIN_NATIVEGDI
-endif
-
-if XWIN_PRIMARYFB
-SRCS_PRIMARYFB = \
- winpfbdd.c
-DEFS_PRIMARYFB = -DXWIN_PRIMARYFB
-endif
-
-if XWIN_RANDR
-SRCS_RANDR = \
- winrandr.c
-DEFS_RANDR = -DXWIN_RANDR
-endif
-
-if XWIN_XV
-SRCS_XV = \
- winvideo.c
-DEFS_XV = -DXWIN_XV
-endif
-
-SRCS = InitInput.c \
- InitOutput.c \
- winallpriv.c \
- winauth.c \
- winblock.c \
- wincmap.c \
- winconfig.c \
- wincreatewnd.c \
- wincursor.c \
- windialogs.c \
- winengine.c \
- winerror.c \
- winglobals.c \
- winkeybd.c \
- winkeyhook.c \
- winmisc.c \
- winmouse.c \
- winmsg.c \
- winmultiwindowclass.c \
- winmultiwindowicons.c \
- winprefs.c \
- winprefsyacc.y \
- winprefslex.l \
- winprocarg.c \
- winregistry.c \
- winscrinit.c \
- winshaddd.c \
- winshadddnl.c \
- winshadgdi.c \
- wintrayicon.c \
- winvalargs.c \
- winwakeup.c \
- winwindow.c \
- winwndproc.c \
- ddraw.h \
- winclipboard.h \
- winconfig.h \
- win.h \
- winkeybd.h \
- winkeynames.h \
- winlayouts.h \
- winmessages.h \
- winmsg.h \
- winms.h \
- winmultiwindowclass.h \
- winprefs.h \
- winresource.h \
- winwindow.h \
- XWin.rc \
- $(top_srcdir)/Xext/dpmsstubs.c \
- $(top_srcdir)/Xi/stubs.c \
- $(top_srcdir)/mi/miinitext.c \
- $(top_srcdir)/fb/fbcmap_mi.c \
- $(SRCS_CLIPBOARD) \
- $(SRCS_MULTIWINDOW) \
- $(SRCS_MULTIWINDOWEXTWM) \
- $(SRCS_NATIVEGDI) \
- $(SRCS_PRIMARYFB) \
- $(SRCS_RANDR) \
- $(SRCS_XV)
-
- DEFS = $(DEFS_CLIPBOARD) \
- $(DEFS_GLX_WINDOWS) \
- $(DEFS_MULTIWINDOW) \
- $(DEFS_MULTIWINDOWEXTWM) \
- $(DEFS_NATIVEGDI) \
- $(DEFS_PRIMARYFB) \
- $(DEFS_RANDR) \
- $(DEFS_XV)
-
-XWin_SOURCES = $(SRCS)
-
-INCLUDES = -I$(top_srcdir)/miext/rootless
-
-XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS)
-XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
-XWin_LDFLAGS = -mwindows -static
-
-.rc.o:
- $(AM_V_GEN)$(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include
-
-winprefsyacc.h: winprefsyacc.c
-winprefslex.c: winprefslex.l winprefsyacc.c winprefsyacc.h
-
-BUILT_SOURCES = winprefsyacc.h winprefsyacc.c winprefslex.c
-CLEANFILES = $(BUILT_SOURCES) $(appman_DATA) $(fileman_DATA) XWin.man XWinrc.man
-
-AM_YFLAGS = -d
-AM_LFLAGS = -i
-AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
- $(XWINMODULES_CFLAGS) \
- -I$(top_srcdir) \
- -Wno-bad-function-cast
-
-MAN_SRCS = XWin.man.pre XWinrc.man.pre
-
-appmandir = $(APP_MAN_DIR)
-appman_DATA = XWin.$(APP_MAN_SUFFIX)
-
-filemandir = $(FILE_MAN_DIR)
-fileman_DATA = XWinrc.$(FILE_MAN_SUFFIX)
-
-XWin.$(APP_MAN_SUFFIX): XWin.man
- -$(AM_V_at)rm -f XWin.$(APP_MAN_SUFFIX)
- $(AM_V_at)$(LN_S) XWin.man XWin.$(APP_MAN_SUFFIX)
-
-XWinrc.$(FILE_MAN_SUFFIX): XWinrc.man
- -$(AM_V_at)rm -f XWinrc.$(FILE_MAN_SUFFIX)
- $(AM_V_at)$(LN_S) XWinrc.man XWinrc.$(FILE_MAN_SUFFIX)
-
-EXTRAMANDEFS = -D__logdir__=$(logdir) -D__sysconfdir__=$(sysconfdir) -D__datadir__=$(datadir)
-
-xwinconfigdir = $(sysconfdir)/X11
-xwinconfig_DATA = system.XWinrc
-
-include $(top_srcdir)/cpprules.in
-
-install-exec-hook:
- (cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) XWin$(EXEEXT) X)
-
-EXTRA_DIST = \
- $(MAN_SRCS) \
- $(xwinconfig_DATA) \
- X.ico \
- XWin.rc \
- xlaunch/config.cc \
- xlaunch/COPYING \
- xlaunch/main.cc \
- xlaunch/resources/dialog.rc \
- xlaunch/resources/fullscreen.bmp \
- xlaunch/resources/images.rc \
- xlaunch/resources/multiwindow.bmp \
- xlaunch/resources/nodecoration.bmp \
- xlaunch/resources/resources.h \
- xlaunch/resources/resources.rc \
- xlaunch/resources/strings.rc \
- xlaunch/resources/windowed.bmp \
- xlaunch/window/dialog.cc \
- xlaunch/window/dialog.h \
- xlaunch/window/util.cc \
- xlaunch/window/util.h \
- xlaunch/window/window.cc \
- xlaunch/window/window.h \
- xlaunch/window/wizard.cc \
- xlaunch/window/wizard.h
-
-relink:
- $(AM_V_at)rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT)
-
-SUBDIRS = $(GLX_DIR) .
-DIST_SUBDIRS = glx .
+bin_PROGRAMS = XWin + +if XWIN_CLIPBOARD +SRCS_CLIPBOARD = \ + winclipboardinit.c \ + winclipboardtextconv.c \ + winclipboardthread.c \ + winclipboardunicode.c \ + winclipboardwndproc.c \ + winclipboardwrappers.c \ + winclipboardxevents.c +DEFS_CLIPBOARD = -DXWIN_CLIPBOARD +endif + +if XWIN_GLX_WINDOWS +GLX_DIR = glx +DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS +XWIN_GLX_LIBS = $(top_builddir)/hw/xwin/glx/libXwinGLX.la +XWIN_GLX_LINK_FLAGS = -lopengl32 +endif + +if XWIN_MULTIWINDOW +SRCS_MULTIWINDOW = \ + winmultiwindowshape.c \ + winmultiwindowwindow.c \ + winmultiwindowwm.c \ + winmultiwindowwndproc.c +DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW +endif + +if XWIN_MULTIWINDOWEXTWM +SRCS_MULTIWINDOWEXTWM = \ + winwin32rootless.c \ + winwin32rootlesswindow.c \ + winwin32rootlesswndproc.c \ + winwindowswm.c +DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM +MULTIWINDOWEXTWM_LIBS = $(top_builddir)/miext/rootless/librootless.la +endif + +if XWIN_NATIVEGDI +SRCS_NATIVEGDI = \ + winclip.c \ + winfillsp.c \ + winfont.c \ + wingc.c \ + wingetsp.c \ + winnativegdi.c \ + winpixmap.c \ + winpolyline.c \ + winrop.c \ + winsetsp.c +DEFS_NATIVEGDI = -DXWIN_NATIVEGDI +endif + +if XWIN_PRIMARYFB +SRCS_PRIMARYFB = \ + winpfbdd.c +DEFS_PRIMARYFB = -DXWIN_PRIMARYFB +endif + +if XWIN_RANDR +SRCS_RANDR = \ + winrandr.c +DEFS_RANDR = -DXWIN_RANDR +endif + +if XWIN_XV +SRCS_XV = \ + winvideo.c +DEFS_XV = -DXWIN_XV +endif + +SRCS = InitInput.c \ + InitOutput.c \ + winallpriv.c \ + winauth.c \ + winblock.c \ + wincmap.c \ + winconfig.c \ + wincreatewnd.c \ + wincursor.c \ + windialogs.c \ + winengine.c \ + winerror.c \ + winglobals.c \ + winkeybd.c \ + winkeyhook.c \ + winmisc.c \ + winmouse.c \ + winmsg.c \ + winmultiwindowclass.c \ + winmultiwindowicons.c \ + winprefs.c \ + winprefsyacc.y \ + winprefslex.l \ + winprocarg.c \ + winregistry.c \ + winscrinit.c \ + winshaddd.c \ + winshadddnl.c \ + winshadgdi.c \ + wintrayicon.c \ + winvalargs.c \ + winwakeup.c \ + winwindow.c \ + winwndproc.c \ + ddraw.h \ + winclipboard.h \ + winconfig.h \ + win.h \ + winkeybd.h \ + winkeynames.h \ + winlayouts.h \ + winmessages.h \ + winmsg.h \ + winms.h \ + winmultiwindowclass.h \ + winprefs.h \ + winresource.h \ + winwindow.h \ + XWin.rc \ + $(top_srcdir)/Xext/dpmsstubs.c \ + $(top_srcdir)/Xi/stubs.c \ + $(top_srcdir)/mi/miinitext.c \ + $(top_srcdir)/fb/fbcmap_mi.c \ + $(SRCS_CLIPBOARD) \ + $(SRCS_MULTIWINDOW) \ + $(SRCS_MULTIWINDOWEXTWM) \ + $(SRCS_NATIVEGDI) \ + $(SRCS_PRIMARYFB) \ + $(SRCS_RANDR) \ + $(SRCS_XV) + + DEFS = $(DEFS_CLIPBOARD) \ + $(DEFS_GLX_WINDOWS) \ + $(DEFS_MULTIWINDOW) \ + $(DEFS_MULTIWINDOWEXTWM) \ + $(DEFS_NATIVEGDI) \ + $(DEFS_PRIMARYFB) \ + $(DEFS_RANDR) \ + $(DEFS_XV) + +XWin_SOURCES = $(SRCS) + +INCLUDES = -I$(top_srcdir)/miext/rootless + +XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) +XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS) +XWin_LDFLAGS = -mwindows -static + +.rc.o: + $(AM_V_GEN)$(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include + +winprefsyacc.h: winprefsyacc.c +winprefslex.c: winprefslex.l winprefsyacc.c winprefsyacc.h + +BUILT_SOURCES = winprefsyacc.h winprefsyacc.c winprefslex.c +CLEANFILES = $(BUILT_SOURCES) + +AM_YFLAGS = -d +AM_LFLAGS = -i +AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \ + $(XWINMODULES_CFLAGS) \ + -I$(top_srcdir) \ + -Wno-bad-function-cast + +xwinconfigdir = $(sysconfdir)/X11 +xwinconfig_DATA = system.XWinrc + +install-exec-hook: + (cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) XWin$(EXEEXT) X) + +EXTRA_DIST = \ + $(xwinconfig_DATA) \ + X.ico \ + XWin.rc \ + xlaunch/config.cc \ + xlaunch/COPYING \ + xlaunch/main.cc \ + xlaunch/resources/dialog.rc \ + xlaunch/resources/fullscreen.bmp \ + xlaunch/resources/images.rc \ + xlaunch/resources/multiwindow.bmp \ + xlaunch/resources/nodecoration.bmp \ + xlaunch/resources/resources.h \ + xlaunch/resources/resources.rc \ + xlaunch/resources/strings.rc \ + xlaunch/resources/windowed.bmp \ + xlaunch/window/dialog.cc \ + xlaunch/window/dialog.h \ + xlaunch/window/util.cc \ + xlaunch/window/util.h \ + xlaunch/window/window.cc \ + xlaunch/window/window.h \ + xlaunch/window/wizard.cc \ + xlaunch/window/wizard.h + +relink: + $(AM_V_at)rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT) + +SUBDIRS = man $(GLX_DIR) . +DIST_SUBDIRS = man glx . diff --git a/xorg-server/hw/xwin/XWin.exe.manifest b/xorg-server/hw/xwin/XWin.exe.manifest new file mode 100644 index 000000000..5668383a9 --- /dev/null +++ b/xorg-server/hw/xwin/XWin.exe.manifest @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <description>The XWin X Windows server for Cygwin.</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+ </dependency>
+</assembly>
diff --git a/xorg-server/hw/xwin/man/Makefile.am b/xorg-server/hw/xwin/man/Makefile.am new file mode 100644 index 000000000..d19c2729f --- /dev/null +++ b/xorg-server/hw/xwin/man/Makefile.am @@ -0,0 +1,3 @@ +include $(top_srcdir)/manpages.am +appman_PRE = XWin.man +fileman_PRE = XWinrc.man diff --git a/xorg-server/hw/xwin/XWin.man.pre b/xorg-server/hw/xwin/man/XWin.man index 356eb625d..51268f69a 100644 --- a/xorg-server/hw/xwin/XWin.man.pre +++ b/xorg-server/hw/xwin/man/XWin.man @@ -1,346 +1,346 @@ -.TH XWIN 1 __vendorversion__
-.SH NAME
-XWin \- X Server for the Cygwin environment on Microsoft Windows
-
-
-.SH SYNOPSIS
-.B XWin
-[ options ] ...
-
-
-.SH DESCRIPTION
-\fIXWin\fP is an X Server for the X Window System on the Cygwin environment
-running on Microsoft Windows.
-
-
-.SH MODES
-\fIXWin\fP can operate in 3 different modes:
-.br
-* \fISingle Window\fP: This is the default mode. Each X screen
-appears as a single \fIWindows\fP window and all X windows are contained
-within this window.
-(In X terminology, the \fIWindows\fP window contains the root window for
-the screen)
-.br
-* \fIMulti-Window\fP: In this mode \fIXWin\fP uses its own integrated
-window manager in order to handle the top-level X windows, in such a
-way that they appear as normal \fIWindows\fP windows.
-.br
-* \fIRootless\fP: In this mode the X server works in a window
-containing the whole screen but this root window (traditionally covered with an X hatch
-pattern) is hidden from view, so only top-level X windows are seen.
-
-.SH OPTIONS
-In addition to the normal server options described in the \fIXserver(1)\fP
-manual page, \fIXWin\fP accepts the following command line switches,
-\fIall\fP of which are optional:
-
-.SH OPTIONS CONTROLLING WINDOWING MODE
-Only one of these options may be specified.
-.TP 8
-.B (default)
-Windowed or rooted mode.
-Each X screen appears as a single \fIWindows\fP window and all X windows are
-contained within those windows.
-.TP 8
-.B \-multiwindow
-Each top-level X window appears in its own \fIWindows\fP window.
-Also start the integrated \fIWindows\fP-based window manager.
-.TP 8
-.B \-rootless
-Run the server in rootless mode.
-The X server works on a window covering the whole screen but the root window
-is hidden from view.
-.TP 8
-.B \-mwextwm
-Experimental.
-The mode combines \fB\-rootless\fP mode drawing with native \fIWindows\fP
-window frames managed by the experimental external window manager \fIxwinwm\fP.
-.PP
-\fBNOTE:\fP \fI-multiwindow\fP mode uses its own internal window manager.
-All other modes require an external window manager in order to move, resize, and perform other
-operations on the individual X windows.
-
-.SH OPTIONS FOR SPECIFYING X SCREENS
-An X display may be composed of multiple screens.
-The default behaviour is to create a single screen 0 that is roughly the
-size of useful area of the primary monitor (allowing for any window
-decorations and the task-bar).
-
-Screen specific parameters, such as \fB\-fullscreen\fP, can be applied as a
-default to all screens by placing those screen specific parameters
-before any \fB\-screen\fP parameter. Screen specific parameters placed after
-the first \fB\-screen\fP parameter will apply only to the immediately
-preceeding \fB\-screen\fP parameter.
-.TP 8
-.B \-[no]multimonitors or \-[no]multiplemonitors
-Create a screen 0 that covers all monitors [the primary monitor] on a system with
-multiple monitors.
-This option is currently enabled by default in \fB\-multiwindow\fP mode.
-.TP 8
-.B "\-screen \fIscreen_number\fP [\fIW\fP \fIH\fP [\fIX\fP \fIY\fP] | [[\fIW\fPx\fIH\fP[+\fIX\fP+\fIY\fP]][@\fIM\fP]] ] "
-Create screen number
-.I screen_number
-and optionally specify it's
-.I height,
-.I width
-and
-.I initial position.
-Additionally a
-.I
-monitor number
-(which count from 1) can be specified to place the screen on,
-at which point, all coordinates become relative to that monitor.
-Screen numbers must be contiguous starting from zero and cannot be duplicated.
-
-Examples:
-
-.I " -screen 0 @1 ; on 1st monitor using its full resolution (the default)"
-
-.I " -screen 0 800x600+100+100@2 ; on 2nd monitor offset 100,100 size 800x600"
-
-.I " -screen 0 1024x768@3 ; on 3rd monitor size 1024x768"
-
-.SH OPTIONS CONTROLLING THE APPEARANCE OF THE X SCREEN WINDOWS
-These parameters only apply to windowed mode screens i.e. not
-in \fB-multwindow\fP or \fB-rootless\fP mode
-.TP 8
-.B "\-fullscreen"
-The X server window takes the full screen, covering completely the
-\fIWindows\fP desktop.
-.TP 8
-.B \-nodecoration
-Do not give the Cygwin/X window a \fIWindows\fP window border, title bar,
-etc.
-This parameter is ignored when the \fB\-fullscreen\fP parameter is specified.
-.TP 8
-.B \-scrollbars
-In windowed mode, allow screens bigger than the \fIWindows\fP desktop.
-Moreover, if the window has decorations, one can now resize it.
-This parameter is ignored when the \fB\-fullscreen\fP parameter is specified.
-
-
-.SH OPTIONS CONTROLLING WINDOWS INTEGRATION
-.TP 8
-.B \-[no]clipboard
-Enables [disables] the integration between the Cygwin/X clipboard and
-\fIWindows\fP clipboard. The default is enabled.
-.TP 8
-.B "\-emulate3buttons [\fItimeout\fP]"
-Emulate a three button mouse; pressing both buttons within
-.I timeout
-milliseconds causes an emulated middle button press. The default
-.I timeout
-is 50 milliseconds. Note that most mice with scroll wheel have middle
-button functionality, usually you will need this option only if you have
-a two button mouse without scroll wheel.
-.TP 8
-.B \-[no]keyhook
-Enable [disable] a low-level keyboard hook for catching
-special keypresses like Menu and Alt+Tab and passing them to the X
-Server instead of letting \fIWindows\fP handle them.
-.TP 8
-.B \-lesspointer
-Normally the \fIWindows\fP mouse cursor is hidden when the mouse is
-over an active Cygwin/X window. This option causes the mouse cursor
-also to be hidden when it is over an inactive Cygwin/X window. This
-prevents the \fIWindows\fP mouse cursor from being drawn on top of the X
-cursor.
-This parameter has no effect unless \fB-swcursor\fP is also specified.
-.TP 8
-.B \-swcursor
-Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead.
-.TP 8
-.B \-[no]trayicon
-Do not create a tray icon. Default is to create one
-icon per screen. You can globally disable tray icons with
-\fB\-notrayicon\fP, then enable it for specific screens with
-\fB\-trayicon\fP for those screens.
-.TP 8
-.B \-nounicodeclipboard
-Do not use Unicode clipboard even if on a NT-based platform.
-.TP 8
-.B \-[no]unixkill
-Enable or disable the \fICtrl-Alt-Backspace\fP key combination as a
-signal to exit the X Server. The \fICtrl-Alt-Backspace\fP key combination
-is disabled by default.
-.TP 8
-.B \-[no]winkill
-Enable or disable the \fIAlt-F4\fP key combination as a signal to exit the
-X Server.
-The \fIAlt-F4\fP key combination is enabled by default.
-
-.SH DRAWING ENGINE OPTIONS
-.TP 8
-.B "\-clipupdates \fInum_boxes\fP"
-Specify an optional threshold, above which the regions in a shadow
-update operation will be collected into a GDI clipping region. The
-clipping region is then used to do a single bit block transfer that is
-constrained to the updated area by the clipping region. There is some
-overhead involved in creating, installing, destroying, and removing
-the clipping region, thus there may not be much benefit for a small
-number of boxes (less than 10). It is even possible that this
-functionality does not provide a benefit at any number of boxes; we
-can only determine the usefulness of this feature through testing.
-This option probably has limited effect on current \fIWindows\fP versions
-as they already perform GDI batching.
-This parameter works in conjunction with engines 1, 2, and 4 (Shadow
-GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking,
-respectively).
-.TP 8
-.B "\-engine \fIengine_type_id\fP"
-This option, which is intended for Cygwin/X developers,
-overrides the server's automatically selected engine type. This
-parameter will be ignored if the specified engine type is not
-supported on the current system. The supported engine type ids are 1
-- Shadow GDI, 2 - Shadow DirectDraw, and 4 - Shadow DirectDraw Non-Locking.
-Additionally, there are engines with type ids
-8 - Primary DirectDraw (obsolete) and 16 - Native GDI (experimental and barely functional).
-Default behavior is to determine the engine with optimum performance that
-supports the specified depth and window configuration.
-
-.SH FULLSCREEN OPTIONS
-.TP 8
-.B "\-depth \fIdepth\fP"
-Specify the color depth, in bits per pixel, to use when running in
-fullscreen with a DirectDraw engine. This parameter is ignored if
-\fB\-fullscreen\fP is not specified.
-.TP 8
-.B "\-refresh \fIrate_in_Hz\fP"
-Specify an optional refresh rate to use when running in
-fullscreen with a DirectDraw engine. This parameter is ignored if
-\fB\-fullscreen\fP is not specified.
-
-.SH MISCELLANEOUS OPTIONS
-See also the normal server options described in the \fIXserver(1)\fP
-manual page
-
-.TP 8
-.B \-help
-Write a help text listing supported command line options and their description to the console.
-.TP 8
-.B \-ignoreinput
-Ignore keyboard and mouse input. This is usually only used for testing
-and debugging purposes.
-.TP 8
-.B "\-logfile \fIfilename\fP"
-Change the server log file from the default of \fI
-__logdir__/XWin.n.log\fP,
-where \fIn\fP is the display number of the XWin server, to \fIfilename\fP.
-.TP 8
-.B "\-logverbose \fIlevel\fP"
-Control the degree of verbosity of the log messages with the integer
-parameter \fIlevel\fP. For \fIlevel\fP=0 only fatal errors are
-reported, for \fIlevel\fP=1 simple information about
-configuration is also given, for \fIlevel\fP=2 (default)
-additional runtime information is recorded
-and for \fIlevel\fP=3 detailed log
-information (including trace and debug output) is produced. Bigger
-values will yield a still more detailed debug output.
-.TP 8
-.B \-silent-dup-error
-If another instance of \fIXWin\fP with the same display number is found running,
-exit silently and don't display any error message.
-.TP 8
-.B "\-xkblayout \fIlayout\fP"
-.TP 8
-.B "\-xkbmodel \fImodel\fP"
-.TP 8
-.B "\-xkboptions \fIoption\fP"
-.TP 8
-.B "\-xkbrules \fIrule\fP"
-.TP 8
-.B "\-xkbvariant \fIvariant\fp"
-These options configure the xkeyboard extension to load
-a particular keyboard map as the X server starts. The behavior is similar
-to the \fIsetxkbmap\fP program. The layout data is located at \fI
-__datadir__/X11/xkb/\fP. Additional information is found in the
-README files therein and in the man page of \fIsetxkbmap\fP. For example
-in order to load a German layout for a pc105 keyboard one uses
-the options:
-.br
-.I " \-xkblayout de \-xkbmodel pc105"
-
-Alternatively one may use the \fIsetxkbmap\fP program after \fIXWin\fP is
-running.
-
-The default is to select a configuration matching your current layout as
-reported by \fIWindows\fP, if known, or the default X server configuration
-if no matching keyboard configuration was found.
-
-.SH UNDOCUMENTED OPTIONS
-These options are undocumented. Do not use them.
-
-.TP 8
-.B \-emulatepseudo
-Create a depth 8 PseudoColor visual when running in depths 15, 16, 24,
-or 32, collectively known as TrueColor depths.
-Color map manipulation is not supported, so the PseudoColor visual will
-not have the correct colors.
-This option is intended to allow applications which only work with a depth 8
-visual to operate in TrueColor modes.
-.TP 8
-.B \-internalwm
-Run the internal window manager.
-
-.SH LOG FILE
-As it runs \fIXWin\fP writes messages indicating the most relevant events
-to the console
-from which it was called and to a log file that by default is located at \fI
-__logdir__/XWin.0.log\fP. This file is mainly for debugging purposes.
-
-
-.SH PREFERENCES FILE
-On startup \fIXWin\fP looks for the file \fI$HOME/.XWinrc\fP or, if
-the previous file does not exist, \fI
-__sysconfdir__/X11/system.XWinrc\fP. \fI.XWinrc\fP allows setting
-preferences for the following:
-.br
-* To include items into the menu associated with the \fIXWin\fP icon
-which is in the \fIWindows\fP system tray. This functions in all
-modes that have a tray icon.
-.br
-* To include items in the system menu which is associated with the \fIWindows\fP
-window that \fIXWin -multiwindow\fP produces for each top-level X
-window, in both the generic case and for particular programs.
-.br
-* To change the icon that is associated to the \fIWindows\fP window that
-\fIXWin -multiwindow\fP produces for each top-level X-window.
-.br
-* To change the style that is associated to the \fIWindows\fP window that
-\fXWin I-multiwindow\fP produces for each top-level X window.
-.PP
-The format of the \fI.XWinrc\fP file is given in the man page XWinrc(5).
-
-.SH EXAMPLES
-Need some examples
-
-
-.SH "SEE ALSO"
-X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(__filemansuffix__), setxkbmap(1)
-
-
-.SH BUGS
-.I XWin
-and this man page still have many limitations. Some of the more obvious
-ones are:
-.br
-- The display mode can not be changed once the X server has started.
-.br
-- The \fIXWin\fP software is continuously developing; it is therefore possible that
-this man page is not up to date. It is always prudent to
-look also at the output of \fIXWin -help\fP in order to
-check the options that are operative.
-
-
-.SH AUTHORS
-This list is by no means complete, but direct contributors to the
-Cygwin/X project include (in alphabetical order by last name): Stuart
-Adamson, Michael Bax, Jehan Bing, Lev Bishop, Dr. Peter Busch, Biju G
-C, Robert Collins, Nick Crabtree, Early Ehlinger, Christopher Faylor,
-John Fortin, Brian Genisio, Fabrizio Gennari, Alexander Gottwald, Ralf
-Habacker, Colin Harrison, Matthieu Herrb, Alan Hourihane, Pierre A
-Humblet, Harold L Hunt II, Dakshinamurthy Karra, Joe Krahn,
-Paul Loewenstein, Kensuke Matsuzaki,
-Takuma Murakami, Earle F. Philhower III, Benjamin Riefenstahl, Yaakov Selkowitz,
-Suhaib Siddiqi, Jack Tanner, Jon Turney and Nicholas Wourms.
+.TH XWIN 1 __vendorversion__ +.SH NAME +XWin \- X Server for the Cygwin environment on Microsoft Windows + + +.SH SYNOPSIS +.B XWin +[ options ] ... + + +.SH DESCRIPTION +\fIXWin\fP is an X Server for the X Window System on the Cygwin environment +running on Microsoft Windows. + + +.SH MODES +\fIXWin\fP can operate in 3 different modes: +.br +* \fISingle Window\fP: This is the default mode. Each X screen +appears as a single \fIWindows\fP window and all X windows are contained +within this window. +(In X terminology, the \fIWindows\fP window contains the root window for +the screen) +.br +* \fIMulti-Window\fP: In this mode \fIXWin\fP uses its own integrated +window manager in order to handle the top-level X windows, in such a +way that they appear as normal \fIWindows\fP windows. +.br +* \fIRootless\fP: In this mode the X server works in a window +containing the whole screen but this root window (traditionally covered with an X hatch +pattern) is hidden from view, so only top-level X windows are seen. + +.SH OPTIONS +In addition to the normal server options described in the \fIXserver(1)\fP +manual page, \fIXWin\fP accepts the following command line switches, +\fIall\fP of which are optional: + +.SH OPTIONS CONTROLLING WINDOWING MODE +Only one of these options may be specified. +.TP 8 +.B (default) +Windowed or rooted mode. +Each X screen appears as a single \fIWindows\fP window and all X windows are +contained within those windows. +.TP 8 +.B \-multiwindow +Each top-level X window appears in its own \fIWindows\fP window. +Also start the integrated \fIWindows\fP-based window manager. +.TP 8 +.B \-rootless +Run the server in rootless mode. +The X server works on a window covering the whole screen but the root window +is hidden from view. +.TP 8 +.B \-mwextwm +Experimental. +The mode combines \fB\-rootless\fP mode drawing with native \fIWindows\fP +window frames managed by the experimental external window manager \fIxwinwm\fP. +.PP +\fBNOTE:\fP \fI-multiwindow\fP mode uses its own internal window manager. +All other modes require an external window manager in order to move, resize, and perform other +operations on the individual X windows. + +.SH OPTIONS FOR SPECIFYING X SCREENS +An X display may be composed of multiple screens. +The default behaviour is to create a single screen 0 that is roughly the +size of useful area of the primary monitor (allowing for any window +decorations and the task-bar). + +Screen specific parameters, such as \fB\-fullscreen\fP, can be applied as a +default to all screens by placing those screen specific parameters +before any \fB\-screen\fP parameter. Screen specific parameters placed after +the first \fB\-screen\fP parameter will apply only to the immediately +preceeding \fB\-screen\fP parameter. +.TP 8 +.B \-[no]multimonitors or \-[no]multiplemonitors +Create a screen 0 that covers all monitors [the primary monitor] on a system with +multiple monitors. +This option is currently enabled by default in \fB\-multiwindow\fP mode. +.TP 8 +.B "\-screen \fIscreen_number\fP [\fIW\fP \fIH\fP [\fIX\fP \fIY\fP] | [[\fIW\fPx\fIH\fP[+\fIX\fP+\fIY\fP]][@\fIM\fP]] ] " +Create screen number +.I screen_number +and optionally specify it's +.I height, +.I width +and +.I initial position. +Additionally a +.I +monitor number +(which count from 1) can be specified to place the screen on, +at which point, all coordinates become relative to that monitor. +Screen numbers must be contiguous starting from zero and cannot be duplicated. + +Examples: + +.I " -screen 0 @1 ; on 1st monitor using its full resolution (the default)" + +.I " -screen 0 800x600+100+100@2 ; on 2nd monitor offset 100,100 size 800x600" + +.I " -screen 0 1024x768@3 ; on 3rd monitor size 1024x768" + +.SH OPTIONS CONTROLLING THE APPEARANCE OF THE X SCREEN WINDOWS +These parameters only apply to windowed mode screens i.e. not +in \fB-multwindow\fP or \fB-rootless\fP mode +.TP 8 +.B "\-fullscreen" +The X server window takes the full screen, covering completely the +\fIWindows\fP desktop. +.TP 8 +.B \-nodecoration +Do not give the Cygwin/X window a \fIWindows\fP window border, title bar, +etc. +This parameter is ignored when the \fB\-fullscreen\fP parameter is specified. +.TP 8 +.B \-scrollbars +In windowed mode, allow screens bigger than the \fIWindows\fP desktop. +Moreover, if the window has decorations, one can now resize it. +This parameter is ignored when the \fB\-fullscreen\fP parameter is specified. + + +.SH OPTIONS CONTROLLING WINDOWS INTEGRATION +.TP 8 +.B \-[no]clipboard +Enables [disables] the integration between the Cygwin/X clipboard and +\fIWindows\fP clipboard. The default is enabled. +.TP 8 +.B "\-emulate3buttons [\fItimeout\fP]" +Emulate a three button mouse; pressing both buttons within +.I timeout +milliseconds causes an emulated middle button press. The default +.I timeout +is 50 milliseconds. Note that most mice with scroll wheel have middle +button functionality, usually you will need this option only if you have +a two button mouse without scroll wheel. +.TP 8 +.B \-[no]keyhook +Enable [disable] a low-level keyboard hook for catching +special keypresses like Menu and Alt+Tab and passing them to the X +Server instead of letting \fIWindows\fP handle them. +.TP 8 +.B \-lesspointer +Normally the \fIWindows\fP mouse cursor is hidden when the mouse is +over an active Cygwin/X window. This option causes the mouse cursor +also to be hidden when it is over an inactive Cygwin/X window. This +prevents the \fIWindows\fP mouse cursor from being drawn on top of the X +cursor. +This parameter has no effect unless \fB-swcursor\fP is also specified. +.TP 8 +.B \-swcursor +Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead. +.TP 8 +.B \-[no]trayicon +Do not create a tray icon. Default is to create one +icon per screen. You can globally disable tray icons with +\fB\-notrayicon\fP, then enable it for specific screens with +\fB\-trayicon\fP for those screens. +.TP 8 +.B \-nounicodeclipboard +Do not use Unicode clipboard even if on a NT-based platform. +.TP 8 +.B \-[no]unixkill +Enable or disable the \fICtrl-Alt-Backspace\fP key combination as a +signal to exit the X Server. The \fICtrl-Alt-Backspace\fP key combination +is disabled by default. +.TP 8 +.B \-[no]winkill +Enable or disable the \fIAlt-F4\fP key combination as a signal to exit the +X Server. +The \fIAlt-F4\fP key combination is enabled by default. + +.SH DRAWING ENGINE OPTIONS +.TP 8 +.B "\-clipupdates \fInum_boxes\fP" +Specify an optional threshold, above which the regions in a shadow +update operation will be collected into a GDI clipping region. The +clipping region is then used to do a single bit block transfer that is +constrained to the updated area by the clipping region. There is some +overhead involved in creating, installing, destroying, and removing +the clipping region, thus there may not be much benefit for a small +number of boxes (less than 10). It is even possible that this +functionality does not provide a benefit at any number of boxes; we +can only determine the usefulness of this feature through testing. +This option probably has limited effect on current \fIWindows\fP versions +as they already perform GDI batching. +This parameter works in conjunction with engines 1, 2, and 4 (Shadow +GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking, +respectively). +.TP 8 +.B "\-engine \fIengine_type_id\fP" +This option, which is intended for Cygwin/X developers, +overrides the server's automatically selected engine type. This +parameter will be ignored if the specified engine type is not +supported on the current system. The supported engine type ids are 1 +- Shadow GDI, 2 - Shadow DirectDraw, and 4 - Shadow DirectDraw Non-Locking. +Additionally, there are engines with type ids +8 - Primary DirectDraw (obsolete) and 16 - Native GDI (experimental and barely functional). +Default behavior is to determine the engine with optimum performance that +supports the specified depth and window configuration. + +.SH FULLSCREEN OPTIONS +.TP 8 +.B "\-depth \fIdepth\fP" +Specify the color depth, in bits per pixel, to use when running in +fullscreen with a DirectDraw engine. This parameter is ignored if +\fB\-fullscreen\fP is not specified. +.TP 8 +.B "\-refresh \fIrate_in_Hz\fP" +Specify an optional refresh rate to use when running in +fullscreen with a DirectDraw engine. This parameter is ignored if +\fB\-fullscreen\fP is not specified. + +.SH MISCELLANEOUS OPTIONS +See also the normal server options described in the \fIXserver(1)\fP +manual page + +.TP 8 +.B \-help +Write a help text listing supported command line options and their description to the console. +.TP 8 +.B \-ignoreinput +Ignore keyboard and mouse input. This is usually only used for testing +and debugging purposes. +.TP 8 +.B "\-logfile \fIfilename\fP" +Change the server log file from the default of \fI +__logdir__/XWin.n.log\fP, +where \fIn\fP is the display number of the XWin server, to \fIfilename\fP. +.TP 8 +.B "\-logverbose \fIlevel\fP" +Control the degree of verbosity of the log messages with the integer +parameter \fIlevel\fP. For \fIlevel\fP=0 only fatal errors are +reported, for \fIlevel\fP=1 simple information about +configuration is also given, for \fIlevel\fP=2 (default) +additional runtime information is recorded +and for \fIlevel\fP=3 detailed log +information (including trace and debug output) is produced. Bigger +values will yield a still more detailed debug output. +.TP 8 +.B \-silent-dup-error +If another instance of \fIXWin\fP with the same display number is found running, +exit silently and don't display any error message. +.TP 8 +.B "\-xkblayout \fIlayout\fP" +.TP 8 +.B "\-xkbmodel \fImodel\fP" +.TP 8 +.B "\-xkboptions \fIoption\fP" +.TP 8 +.B "\-xkbrules \fIrule\fP" +.TP 8 +.B "\-xkbvariant \fIvariant\fp" +These options configure the xkeyboard extension to load +a particular keyboard map as the X server starts. The behavior is similar +to the \fIsetxkbmap\fP program. The layout data is located at \fI +__datadir__/X11/xkb/\fP. Additional information is found in the +README files therein and in the man page of \fIsetxkbmap\fP. For example +in order to load a German layout for a pc105 keyboard one uses +the options: +.br +.I " \-xkblayout de \-xkbmodel pc105" + +Alternatively one may use the \fIsetxkbmap\fP program after \fIXWin\fP is +running. + +The default is to select a configuration matching your current layout as +reported by \fIWindows\fP, if known, or the default X server configuration +if no matching keyboard configuration was found. + +.SH UNDOCUMENTED OPTIONS +These options are undocumented. Do not use them. + +.TP 8 +.B \-emulatepseudo +Create a depth 8 PseudoColor visual when running in depths 15, 16, 24, +or 32, collectively known as TrueColor depths. +Color map manipulation is not supported, so the PseudoColor visual will +not have the correct colors. +This option is intended to allow applications which only work with a depth 8 +visual to operate in TrueColor modes. +.TP 8 +.B \-internalwm +Run the internal window manager. + +.SH LOG FILE +As it runs \fIXWin\fP writes messages indicating the most relevant events +to the console +from which it was called and to a log file that by default is located at \fI +__logdir__/XWin.0.log\fP. This file is mainly for debugging purposes. + + +.SH PREFERENCES FILE +On startup \fIXWin\fP looks for the file \fI$HOME/.XWinrc\fP or, if +the previous file does not exist, \fI +__sysconfdir__/X11/system.XWinrc\fP. \fI.XWinrc\fP allows setting +preferences for the following: +.br +* To include items into the menu associated with the \fIXWin\fP icon +which is in the \fIWindows\fP system tray. This functions in all +modes that have a tray icon. +.br +* To include items in the system menu which is associated with the \fIWindows\fP +window that \fIXWin -multiwindow\fP produces for each top-level X +window, in both the generic case and for particular programs. +.br +* To change the icon that is associated to the \fIWindows\fP window that +\fIXWin -multiwindow\fP produces for each top-level X-window. +.br +* To change the style that is associated to the \fIWindows\fP window that +\fXWin I-multiwindow\fP produces for each top-level X window. +.PP +The format of the \fI.XWinrc\fP file is given in the man page XWinrc(5). + +.SH EXAMPLES +Need some examples + + +.SH "SEE ALSO" +X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(__filemansuffix__), setxkbmap(1) + + +.SH BUGS +.I XWin +and this man page still have many limitations. Some of the more obvious +ones are: +.br +- The display mode can not be changed once the X server has started. +.br +- The \fIXWin\fP software is continuously developing; it is therefore possible that +this man page is not up to date. It is always prudent to +look also at the output of \fIXWin -help\fP in order to +check the options that are operative. + + +.SH AUTHORS +This list is by no means complete, but direct contributors to the +Cygwin/X project include (in alphabetical order by last name): Stuart +Adamson, Michael Bax, Jehan Bing, Lev Bishop, Dr. Peter Busch, Biju G +C, Robert Collins, Nick Crabtree, Early Ehlinger, Christopher Faylor, +John Fortin, Brian Genisio, Fabrizio Gennari, Alexander Gottwald, Ralf +Habacker, Colin Harrison, Matthieu Herrb, Alan Hourihane, Pierre A +Humblet, Harold L Hunt II, Dakshinamurthy Karra, Joe Krahn, +Paul Loewenstein, Kensuke Matsuzaki, +Takuma Murakami, Earle F. Philhower III, Benjamin Riefenstahl, Yaakov Selkowitz, +Suhaib Siddiqi, Jack Tanner, Jon Turney and Nicholas Wourms. diff --git a/xorg-server/hw/xwin/XWinrc.man.pre b/xorg-server/hw/xwin/man/XWinrc.man index 5c1fb979b..5c1fb979b 100644 --- a/xorg-server/hw/xwin/XWinrc.man.pre +++ b/xorg-server/hw/xwin/man/XWinrc.man diff --git a/xorg-server/include/scrnintstr.h b/xorg-server/include/scrnintstr.h index fdb904fa2..9f4fbf3df 100644 --- a/xorg-server/include/scrnintstr.h +++ b/xorg-server/include/scrnintstr.h @@ -1,569 +1,573 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-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 THE
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifndef SCREENINTSTRUCT_H
-#define SCREENINTSTRUCT_H
-
-#include "screenint.h"
-#include "regionstr.h"
-#include "colormap.h"
-#include "cursor.h"
-#include "validate.h"
-#include <X11/Xproto.h>
-#include "dix.h"
-#include "privates.h"
-
-typedef struct _PixmapFormat {
- unsigned char depth;
- unsigned char bitsPerPixel;
- unsigned char scanlinePad;
- } PixmapFormatRec;
-
-typedef struct _Visual {
- VisualID vid;
- short class;
- short bitsPerRGBValue;
- short ColormapEntries;
- short nplanes;/* = log2 (ColormapEntries). This does not
- * imply that the screen has this many planes.
- * it may have more or fewer */
- unsigned long redMask, greenMask, blueMask;
- int offsetRed, offsetGreen, offsetBlue;
- } VisualRec;
-
-typedef struct _Depth {
- unsigned char depth;
- short numVids;
- VisualID *vids; /* block of visual ids for this depth */
- } DepthRec;
-
-typedef struct _ScreenSaverStuff {
- WindowPtr pWindow;
- XID wid;
- char blanked;
- Bool (*ExternalScreenSaver)(
- ScreenPtr /*pScreen*/,
- int /*xstate*/,
- Bool /*force*/);
-} ScreenSaverStuffRec;
-
-
-/*
- * There is a typedef for each screen function pointer so that code that
- * needs to declare a screen function pointer (e.g. in a screen private
- * or as a local variable) can easily do so and retain full type checking.
- */
-
-typedef Bool (* CloseScreenProcPtr)(
- int /*index*/,
- ScreenPtr /*pScreen*/);
-
-typedef void (* QueryBestSizeProcPtr)(
- int /*class*/,
- unsigned short * /*pwidth*/,
- unsigned short * /*pheight*/,
- ScreenPtr /*pScreen*/);
-
-typedef Bool (* SaveScreenProcPtr)(
- ScreenPtr /*pScreen*/,
- int /*on*/);
-
-typedef void (* GetImageProcPtr)(
- DrawablePtr /*pDrawable*/,
- int /*sx*/,
- int /*sy*/,
- int /*w*/,
- int /*h*/,
- unsigned int /*format*/,
- unsigned long /*planeMask*/,
- char * /*pdstLine*/);
-
-typedef void (* GetSpansProcPtr)(
- DrawablePtr /*pDrawable*/,
- int /*wMax*/,
- DDXPointPtr /*ppt*/,
- int* /*pwidth*/,
- int /*nspans*/,
- char * /*pdstStart*/);
-
-typedef void (* SourceValidateProcPtr)(
- DrawablePtr /*pDrawable*/,
- int /*x*/,
- int /*y*/,
- int /*width*/,
- int /*height*/,
- unsigned int /*subWindowMode*/);
-
-typedef Bool (* CreateWindowProcPtr)(
- WindowPtr /*pWindow*/);
-
-typedef Bool (* DestroyWindowProcPtr)(
- WindowPtr /*pWindow*/);
-
-typedef Bool (* PositionWindowProcPtr)(
- WindowPtr /*pWindow*/,
- int /*x*/,
- int /*y*/);
-
-typedef Bool (* ChangeWindowAttributesProcPtr)(
- WindowPtr /*pWindow*/,
- unsigned long /*mask*/);
-
-typedef Bool (* RealizeWindowProcPtr)(
- WindowPtr /*pWindow*/);
-
-typedef Bool (* UnrealizeWindowProcPtr)(
- WindowPtr /*pWindow*/);
-
-typedef void (* RestackWindowProcPtr)(
- WindowPtr /*pWindow*/,
- WindowPtr /*pOldNextSib*/);
-
-typedef int (* ValidateTreeProcPtr)(
- WindowPtr /*pParent*/,
- WindowPtr /*pChild*/,
- VTKind /*kind*/);
-
-typedef void (* PostValidateTreeProcPtr)(
- WindowPtr /*pParent*/,
- WindowPtr /*pChild*/,
- VTKind /*kind*/);
-
-typedef void (* WindowExposuresProcPtr)(
- WindowPtr /*pWindow*/,
- RegionPtr /*prgn*/,
- RegionPtr /*other_exposed*/);
-
-typedef void (* CopyWindowProcPtr)(
- WindowPtr /*pWindow*/,
- DDXPointRec /*ptOldOrg*/,
- RegionPtr /*prgnSrc*/);
-
-typedef void (* ClearToBackgroundProcPtr)(
- WindowPtr /*pWindow*/,
- int /*x*/,
- int /*y*/,
- int /*w*/,
- int /*h*/,
- Bool /*generateExposures*/);
-
-typedef void (* ClipNotifyProcPtr)(
- WindowPtr /*pWindow*/,
- int /*dx*/,
- int /*dy*/);
-
-/* pixmap will exist only for the duration of the current rendering operation */
-#define CREATE_PIXMAP_USAGE_SCRATCH 1
-/* pixmap will be the backing pixmap for a redirected window */
-#define CREATE_PIXMAP_USAGE_BACKING_PIXMAP 2
-/* pixmap will contain a glyph */
-#define CREATE_PIXMAP_USAGE_GLYPH_PICTURE 3
-
-typedef PixmapPtr (* CreatePixmapProcPtr)(
- ScreenPtr /*pScreen*/,
- int /*width*/,
- int /*height*/,
- int /*depth*/,
- unsigned /*usage_hint*/);
-
-typedef Bool (* DestroyPixmapProcPtr)(
- PixmapPtr /*pPixmap*/);
-
-typedef Bool (* RealizeFontProcPtr)(
- ScreenPtr /*pScreen*/,
- FontPtr /*pFont*/);
-
-typedef Bool (* UnrealizeFontProcPtr)(
- ScreenPtr /*pScreen*/,
- FontPtr /*pFont*/);
-
-typedef void (* ConstrainCursorProcPtr)(
- DeviceIntPtr /*pDev*/,
- ScreenPtr /*pScreen*/,
- BoxPtr /*pBox*/);
-
-typedef void (* CursorLimitsProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScreen*/,
- CursorPtr /*pCursor*/,
- BoxPtr /*pHotBox*/,
- BoxPtr /*pTopLeftBox*/);
-
-typedef Bool (* DisplayCursorProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScreen*/,
- CursorPtr /*pCursor*/);
-
-typedef Bool (* RealizeCursorProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScreen*/,
- CursorPtr /*pCursor*/);
-
-typedef Bool (* UnrealizeCursorProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScreen*/,
- CursorPtr /*pCursor*/);
-
-typedef void (* RecolorCursorProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScreen*/,
- CursorPtr /*pCursor*/,
- Bool /*displayed*/);
-
-typedef Bool (* SetCursorPositionProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /*pScreen*/,
- int /*x*/,
- int /*y*/,
- Bool /*generateEvent*/);
-
-typedef Bool (* CreateGCProcPtr)(
- GCPtr /*pGC*/);
-
-typedef Bool (* CreateColormapProcPtr)(
- ColormapPtr /*pColormap*/);
-
-typedef void (* DestroyColormapProcPtr)(
- ColormapPtr /*pColormap*/);
-
-typedef void (* InstallColormapProcPtr)(
- ColormapPtr /*pColormap*/);
-
-typedef void (* UninstallColormapProcPtr)(
- ColormapPtr /*pColormap*/);
-
-typedef int (* ListInstalledColormapsProcPtr) (
- ScreenPtr /*pScreen*/,
- XID* /*pmaps */);
-
-typedef void (* StoreColorsProcPtr)(
- ColormapPtr /*pColormap*/,
- int /*ndef*/,
- xColorItem * /*pdef*/);
-
-typedef void (* ResolveColorProcPtr)(
- unsigned short* /*pred*/,
- unsigned short* /*pgreen*/,
- unsigned short* /*pblue*/,
- VisualPtr /*pVisual*/);
-
-typedef RegionPtr (* BitmapToRegionProcPtr)(
- PixmapPtr /*pPix*/);
-
-typedef void (* SendGraphicsExposeProcPtr)(
- ClientPtr /*client*/,
- RegionPtr /*pRgn*/,
- XID /*drawable*/,
- int /*major*/,
- int /*minor*/);
-
-typedef void (* ScreenBlockHandlerProcPtr)(
- int /*screenNum*/,
- pointer /*blockData*/,
- pointer /*pTimeout*/,
- pointer /*pReadmask*/);
-
-typedef void (* ScreenWakeupHandlerProcPtr)(
- int /*screenNum*/,
- pointer /*wakeupData*/,
- unsigned long /*result*/,
- pointer /*pReadMask*/);
-
-typedef Bool (* CreateScreenResourcesProcPtr)(
- ScreenPtr /*pScreen*/);
-
-typedef Bool (* ModifyPixmapHeaderProcPtr)(
- PixmapPtr /*pPixmap*/,
- int /*width*/,
- int /*height*/,
- int /*depth*/,
- int /*bitsPerPixel*/,
- int /*devKind*/,
- pointer /*pPixData*/);
-
-typedef PixmapPtr (* GetWindowPixmapProcPtr)(
- WindowPtr /*pWin*/);
-
-typedef void (* SetWindowPixmapProcPtr)(
- WindowPtr /*pWin*/,
- PixmapPtr /*pPix*/);
-
-typedef PixmapPtr (* GetScreenPixmapProcPtr)(
- ScreenPtr /*pScreen*/);
-
-typedef void (* SetScreenPixmapProcPtr)(
- PixmapPtr /*pPix*/);
-
-typedef void (* MarkWindowProcPtr)(
- WindowPtr /*pWin*/);
-
-typedef Bool (* MarkOverlappedWindowsProcPtr)(
- WindowPtr /*parent*/,
- WindowPtr /*firstChild*/,
- WindowPtr * /*pLayerWin*/);
-
-typedef int (* ConfigNotifyProcPtr)(
- WindowPtr /*pWin*/,
- int /*x*/,
- int /*y*/,
- int /*w*/,
- int /*h*/,
- int /*bw*/,
- WindowPtr /*pSib*/);
-
-typedef void (* MoveWindowProcPtr)(
- WindowPtr /*pWin*/,
- int /*x*/,
- int /*y*/,
- WindowPtr /*pSib*/,
- VTKind /*kind*/);
-
-typedef void (* ResizeWindowProcPtr)(
- WindowPtr /*pWin*/,
- int /*x*/,
- int /*y*/,
- unsigned int /*w*/,
- unsigned int /*h*/,
- WindowPtr /*pSib*/
-);
-
-typedef WindowPtr (* GetLayerWindowProcPtr)(
- WindowPtr /*pWin*/
-);
-
-typedef void (* HandleExposuresProcPtr)(
- WindowPtr /*pWin*/);
-
-typedef void (* ReparentWindowProcPtr)(
- WindowPtr /*pWin*/,
- WindowPtr /*pPriorParent*/);
-
-typedef void (* SetShapeProcPtr)(
- WindowPtr /*pWin*/,
- int /* kind */);
-
-typedef void (* ChangeBorderWidthProcPtr)(
- WindowPtr /*pWin*/,
- unsigned int /*width*/);
-
-typedef void (* MarkUnrealizedWindowProcPtr)(
- WindowPtr /*pChild*/,
- WindowPtr /*pWin*/,
- Bool /*fromConfigure*/);
-
-typedef Bool (* DeviceCursorInitializeProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScreen */);
-
-typedef void (* DeviceCursorCleanupProcPtr)(
- DeviceIntPtr /* pDev */,
- ScreenPtr /* pScreen */);
-
-typedef struct _Screen {
- int myNum; /* index of this instance in Screens[] */
- ATOM id;
- short x, y, width, height;
- short mmWidth, mmHeight;
- short numDepths;
- unsigned char rootDepth;
- DepthPtr allowedDepths;
- unsigned long rootVisual;
- unsigned long defColormap;
- short minInstalledCmaps, maxInstalledCmaps;
- char backingStoreSupport, saveUnderSupport;
- unsigned long whitePixel, blackPixel;
- GCPtr GCperDepth[MAXFORMATS+1];
- /* next field is a stipple to use as default in
- a GC. we don't build default tiles of all depths
- because they are likely to be of a color
- different from the default fg pixel, so
- we don't win anything by building
- a standard one.
- */
- PixmapPtr PixmapPerDepth[1];
- pointer devPrivate;
- short numVisuals;
- VisualPtr visuals;
- WindowPtr root;
- ScreenSaverStuffRec screensaver;
-
- /* Random screen procedures */
-
- CloseScreenProcPtr CloseScreen;
- QueryBestSizeProcPtr QueryBestSize;
- SaveScreenProcPtr SaveScreen;
- GetImageProcPtr GetImage;
- GetSpansProcPtr GetSpans;
- SourceValidateProcPtr SourceValidate;
-
- /* Window Procedures */
-
- CreateWindowProcPtr CreateWindow;
- DestroyWindowProcPtr DestroyWindow;
- PositionWindowProcPtr PositionWindow;
- ChangeWindowAttributesProcPtr ChangeWindowAttributes;
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- ValidateTreeProcPtr ValidateTree;
- PostValidateTreeProcPtr PostValidateTree;
- WindowExposuresProcPtr WindowExposures;
- CopyWindowProcPtr CopyWindow;
- ClearToBackgroundProcPtr ClearToBackground;
- ClipNotifyProcPtr ClipNotify;
- RestackWindowProcPtr RestackWindow;
-
- /* Pixmap procedures */
-
- CreatePixmapProcPtr CreatePixmap;
- DestroyPixmapProcPtr DestroyPixmap;
-
- /* Font procedures */
-
- RealizeFontProcPtr RealizeFont;
- UnrealizeFontProcPtr UnrealizeFont;
-
- /* Cursor Procedures */
-
- ConstrainCursorProcPtr ConstrainCursor;
- CursorLimitsProcPtr CursorLimits;
- DisplayCursorProcPtr DisplayCursor;
- RealizeCursorProcPtr RealizeCursor;
- UnrealizeCursorProcPtr UnrealizeCursor;
- RecolorCursorProcPtr RecolorCursor;
- SetCursorPositionProcPtr SetCursorPosition;
-
- /* GC procedures */
-
- CreateGCProcPtr CreateGC;
-
- /* Colormap procedures */
-
- CreateColormapProcPtr CreateColormap;
- DestroyColormapProcPtr DestroyColormap;
- InstallColormapProcPtr InstallColormap;
- UninstallColormapProcPtr UninstallColormap;
- ListInstalledColormapsProcPtr ListInstalledColormaps;
- StoreColorsProcPtr StoreColors;
- ResolveColorProcPtr ResolveColor;
-
- /* Region procedures */
-
- BitmapToRegionProcPtr BitmapToRegion;
- SendGraphicsExposeProcPtr SendGraphicsExpose;
-
- /* os layer procedures */
-
- ScreenBlockHandlerProcPtr BlockHandler;
- ScreenWakeupHandlerProcPtr WakeupHandler;
-
- pointer blockData;
- pointer wakeupData;
-
- /* anybody can get a piece of this array */
- PrivateRec *devPrivates;
-
- CreateScreenResourcesProcPtr CreateScreenResources;
- ModifyPixmapHeaderProcPtr ModifyPixmapHeader;
-
- GetWindowPixmapProcPtr GetWindowPixmap;
- SetWindowPixmapProcPtr SetWindowPixmap;
- GetScreenPixmapProcPtr GetScreenPixmap;
- SetScreenPixmapProcPtr SetScreenPixmap;
-
- PixmapPtr pScratchPixmap; /* scratch pixmap "pool" */
-
- unsigned int totalPixmapSize;
-
- MarkWindowProcPtr MarkWindow;
- MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
- ConfigNotifyProcPtr ConfigNotify;
- MoveWindowProcPtr MoveWindow;
- ResizeWindowProcPtr ResizeWindow;
- GetLayerWindowProcPtr GetLayerWindow;
- HandleExposuresProcPtr HandleExposures;
- ReparentWindowProcPtr ReparentWindow;
-
- SetShapeProcPtr SetShape;
-
- ChangeBorderWidthProcPtr ChangeBorderWidth;
- MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
-
- /* Device cursor procedures */
- DeviceCursorInitializeProcPtr DeviceCursorInitialize;
- DeviceCursorCleanupProcPtr DeviceCursorCleanup;
-
- /* set it in driver side if X server can copy the framebuffer content.
- * Meant to be used together with '-background none' option, avoiding
- * malicious users to steal framebuffer's content if that would be the
- * default */
- Bool canDoBGNoneRoot;
-} ScreenRec;
-
-static inline RegionPtr BitmapToRegion(ScreenPtr _pScreen, PixmapPtr pPix) {
- return (*(_pScreen)->BitmapToRegion)(pPix); /* no mi version?! */
-}
-
-typedef struct _ScreenInfo {
- int imageByteOrder;
- int bitmapScanlineUnit;
- int bitmapScanlinePad;
- int bitmapBitOrder;
- int numPixmapFormats;
- PixmapFormatRec
- formats[MAXFORMATS];
- int numScreens;
- ScreenPtr screens[MAXSCREENS];
-} ScreenInfo;
-
-extern _X_EXPORT ScreenInfo screenInfo;
-
-extern _X_EXPORT void InitOutput(
- ScreenInfo * /*pScreenInfo*/,
- int /*argc*/,
- char ** /*argv*/);
-
-#endif /* SCREENINTSTRUCT_H */
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 THE +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef SCREENINTSTRUCT_H +#define SCREENINTSTRUCT_H + +#include "screenint.h" +#include "regionstr.h" +#include "colormap.h" +#include "cursor.h" +#include "validate.h" +#include <X11/Xproto.h> +#include "dix.h" +#include "privates.h" + +typedef struct _PixmapFormat { + unsigned char depth; + unsigned char bitsPerPixel; + unsigned char scanlinePad; + } PixmapFormatRec; + +typedef struct _Visual { + VisualID vid; + short class; + short bitsPerRGBValue; + short ColormapEntries; + short nplanes;/* = log2 (ColormapEntries). This does not + * imply that the screen has this many planes. + * it may have more or fewer */ + unsigned long redMask, greenMask, blueMask; + int offsetRed, offsetGreen, offsetBlue; + } VisualRec; + +typedef struct _Depth { + unsigned char depth; + short numVids; + VisualID *vids; /* block of visual ids for this depth */ + } DepthRec; + +typedef struct _ScreenSaverStuff { + WindowPtr pWindow; + XID wid; + char blanked; + Bool (*ExternalScreenSaver)( + ScreenPtr /*pScreen*/, + int /*xstate*/, + Bool /*force*/); +} ScreenSaverStuffRec; + + +/* + * There is a typedef for each screen function pointer so that code that + * needs to declare a screen function pointer (e.g. in a screen private + * or as a local variable) can easily do so and retain full type checking. + */ + +typedef Bool (* CloseScreenProcPtr)( + int /*index*/, + ScreenPtr /*pScreen*/); + +typedef void (* QueryBestSizeProcPtr)( + int /*class*/, + unsigned short * /*pwidth*/, + unsigned short * /*pheight*/, + ScreenPtr /*pScreen*/); + +typedef Bool (* SaveScreenProcPtr)( + ScreenPtr /*pScreen*/, + int /*on*/); + +typedef void (* GetImageProcPtr)( + DrawablePtr /*pDrawable*/, + int /*sx*/, + int /*sy*/, + int /*w*/, + int /*h*/, + unsigned int /*format*/, + unsigned long /*planeMask*/, + char * /*pdstLine*/); + +typedef void (* GetSpansProcPtr)( + DrawablePtr /*pDrawable*/, + int /*wMax*/, + DDXPointPtr /*ppt*/, + int* /*pwidth*/, + int /*nspans*/, + char * /*pdstStart*/); + +typedef void (* SourceValidateProcPtr)( + DrawablePtr /*pDrawable*/, + int /*x*/, + int /*y*/, + int /*width*/, + int /*height*/, + unsigned int /*subWindowMode*/); + +typedef Bool (* CreateWindowProcPtr)( + WindowPtr /*pWindow*/); + +typedef Bool (* DestroyWindowProcPtr)( + WindowPtr /*pWindow*/); + +typedef Bool (* PositionWindowProcPtr)( + WindowPtr /*pWindow*/, + int /*x*/, + int /*y*/); + +typedef Bool (* ChangeWindowAttributesProcPtr)( + WindowPtr /*pWindow*/, + unsigned long /*mask*/); + +typedef Bool (* RealizeWindowProcPtr)( + WindowPtr /*pWindow*/); + +typedef Bool (* UnrealizeWindowProcPtr)( + WindowPtr /*pWindow*/); + +typedef void (* RestackWindowProcPtr)( + WindowPtr /*pWindow*/, + WindowPtr /*pOldNextSib*/); + +typedef int (* ValidateTreeProcPtr)( + WindowPtr /*pParent*/, + WindowPtr /*pChild*/, + VTKind /*kind*/); + +typedef void (* PostValidateTreeProcPtr)( + WindowPtr /*pParent*/, + WindowPtr /*pChild*/, + VTKind /*kind*/); + +typedef void (* WindowExposuresProcPtr)( + WindowPtr /*pWindow*/, + RegionPtr /*prgn*/, + RegionPtr /*other_exposed*/); + +typedef void (* CopyWindowProcPtr)( + WindowPtr /*pWindow*/, + DDXPointRec /*ptOldOrg*/, + RegionPtr /*prgnSrc*/); + +typedef void (* ClearToBackgroundProcPtr)( + WindowPtr /*pWindow*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + Bool /*generateExposures*/); + +typedef void (* ClipNotifyProcPtr)( + WindowPtr /*pWindow*/, + int /*dx*/, + int /*dy*/); + +/* pixmap will exist only for the duration of the current rendering operation */ +#define CREATE_PIXMAP_USAGE_SCRATCH 1 +/* pixmap will be the backing pixmap for a redirected window */ +#define CREATE_PIXMAP_USAGE_BACKING_PIXMAP 2 +/* pixmap will contain a glyph */ +#define CREATE_PIXMAP_USAGE_GLYPH_PICTURE 3 + +typedef PixmapPtr (* CreatePixmapProcPtr)( + ScreenPtr /*pScreen*/, + int /*width*/, + int /*height*/, + int /*depth*/, + unsigned /*usage_hint*/); + +typedef Bool (* DestroyPixmapProcPtr)( + PixmapPtr /*pPixmap*/); + +typedef Bool (* RealizeFontProcPtr)( + ScreenPtr /*pScreen*/, + FontPtr /*pFont*/); + +typedef Bool (* UnrealizeFontProcPtr)( + ScreenPtr /*pScreen*/, + FontPtr /*pFont*/); + +typedef void (* ConstrainCursorProcPtr)( + DeviceIntPtr /*pDev*/, + ScreenPtr /*pScreen*/, + BoxPtr /*pBox*/); + +typedef void (* CursorLimitsProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/, + BoxPtr /*pHotBox*/, + BoxPtr /*pTopLeftBox*/); + +typedef Bool (* DisplayCursorProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/); + +typedef Bool (* RealizeCursorProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/); + +typedef Bool (* UnrealizeCursorProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/); + +typedef void (* RecolorCursorProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/, + Bool /*displayed*/); + +typedef Bool (* SetCursorPositionProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /*pScreen*/, + int /*x*/, + int /*y*/, + Bool /*generateEvent*/); + +typedef Bool (* CreateGCProcPtr)( + GCPtr /*pGC*/); + +typedef Bool (* CreateColormapProcPtr)( + ColormapPtr /*pColormap*/); + +typedef void (* DestroyColormapProcPtr)( + ColormapPtr /*pColormap*/); + +typedef void (* InstallColormapProcPtr)( + ColormapPtr /*pColormap*/); + +typedef void (* UninstallColormapProcPtr)( + ColormapPtr /*pColormap*/); + +typedef int (* ListInstalledColormapsProcPtr) ( + ScreenPtr /*pScreen*/, + XID* /*pmaps */); + +typedef void (* StoreColorsProcPtr)( + ColormapPtr /*pColormap*/, + int /*ndef*/, + xColorItem * /*pdef*/); + +typedef void (* ResolveColorProcPtr)( + unsigned short* /*pred*/, + unsigned short* /*pgreen*/, + unsigned short* /*pblue*/, + VisualPtr /*pVisual*/); + +typedef RegionPtr (* BitmapToRegionProcPtr)( + PixmapPtr /*pPix*/); + +typedef void (* SendGraphicsExposeProcPtr)( + ClientPtr /*client*/, + RegionPtr /*pRgn*/, + XID /*drawable*/, + int /*major*/, + int /*minor*/); + +typedef void (* ScreenBlockHandlerProcPtr)( + int /*screenNum*/, + pointer /*blockData*/, + pointer /*pTimeout*/, + pointer /*pReadmask*/); + +typedef void (* ScreenWakeupHandlerProcPtr)( + int /*screenNum*/, + pointer /*wakeupData*/, + unsigned long /*result*/, + pointer /*pReadMask*/); + +typedef Bool (* CreateScreenResourcesProcPtr)( + ScreenPtr /*pScreen*/); + +typedef Bool (* ModifyPixmapHeaderProcPtr)( + PixmapPtr /*pPixmap*/, + int /*width*/, + int /*height*/, + int /*depth*/, + int /*bitsPerPixel*/, + int /*devKind*/, + pointer /*pPixData*/); + +typedef PixmapPtr (* GetWindowPixmapProcPtr)( + WindowPtr /*pWin*/); + +typedef void (* SetWindowPixmapProcPtr)( + WindowPtr /*pWin*/, + PixmapPtr /*pPix*/); + +typedef PixmapPtr (* GetScreenPixmapProcPtr)( + ScreenPtr /*pScreen*/); + +typedef void (* SetScreenPixmapProcPtr)( + PixmapPtr /*pPix*/); + +typedef void (* MarkWindowProcPtr)( + WindowPtr /*pWin*/); + +typedef Bool (* MarkOverlappedWindowsProcPtr)( + WindowPtr /*parent*/, + WindowPtr /*firstChild*/, + WindowPtr * /*pLayerWin*/); + +typedef int (* ConfigNotifyProcPtr)( + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + int /*bw*/, + WindowPtr /*pSib*/); + +typedef void (* MoveWindowProcPtr)( + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + WindowPtr /*pSib*/, + VTKind /*kind*/); + +typedef void (* ResizeWindowProcPtr)( + WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + unsigned int /*w*/, + unsigned int /*h*/, + WindowPtr /*pSib*/ +); + +typedef WindowPtr (* GetLayerWindowProcPtr)( + WindowPtr /*pWin*/ +); + +typedef void (* HandleExposuresProcPtr)( + WindowPtr /*pWin*/); + +typedef void (* ReparentWindowProcPtr)( + WindowPtr /*pWin*/, + WindowPtr /*pPriorParent*/); + +typedef void (* SetShapeProcPtr)( + WindowPtr /*pWin*/, + int /* kind */); + +typedef void (* ChangeBorderWidthProcPtr)( + WindowPtr /*pWin*/, + unsigned int /*width*/); + +typedef void (* MarkUnrealizedWindowProcPtr)( + WindowPtr /*pChild*/, + WindowPtr /*pWin*/, + Bool /*fromConfigure*/); + +typedef Bool (* DeviceCursorInitializeProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScreen */); + +typedef void (* DeviceCursorCleanupProcPtr)( + DeviceIntPtr /* pDev */, + ScreenPtr /* pScreen */); + +typedef void (*ConstrainCursorHarderProcPtr)( + DeviceIntPtr, ScreenPtr, int *, int *); + +typedef struct _Screen { + int myNum; /* index of this instance in Screens[] */ + ATOM id; + short x, y, width, height; + short mmWidth, mmHeight; + short numDepths; + unsigned char rootDepth; + DepthPtr allowedDepths; + unsigned long rootVisual; + unsigned long defColormap; + short minInstalledCmaps, maxInstalledCmaps; + char backingStoreSupport, saveUnderSupport; + unsigned long whitePixel, blackPixel; + GCPtr GCperDepth[MAXFORMATS+1]; + /* next field is a stipple to use as default in + a GC. we don't build default tiles of all depths + because they are likely to be of a color + different from the default fg pixel, so + we don't win anything by building + a standard one. + */ + PixmapPtr PixmapPerDepth[1]; + pointer devPrivate; + short numVisuals; + VisualPtr visuals; + WindowPtr root; + ScreenSaverStuffRec screensaver; + + /* Random screen procedures */ + + CloseScreenProcPtr CloseScreen; + QueryBestSizeProcPtr QueryBestSize; + SaveScreenProcPtr SaveScreen; + GetImageProcPtr GetImage; + GetSpansProcPtr GetSpans; + SourceValidateProcPtr SourceValidate; + + /* Window Procedures */ + + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + PositionWindowProcPtr PositionWindow; + ChangeWindowAttributesProcPtr ChangeWindowAttributes; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + ValidateTreeProcPtr ValidateTree; + PostValidateTreeProcPtr PostValidateTree; + WindowExposuresProcPtr WindowExposures; + CopyWindowProcPtr CopyWindow; + ClearToBackgroundProcPtr ClearToBackground; + ClipNotifyProcPtr ClipNotify; + RestackWindowProcPtr RestackWindow; + + /* Pixmap procedures */ + + CreatePixmapProcPtr CreatePixmap; + DestroyPixmapProcPtr DestroyPixmap; + + /* Font procedures */ + + RealizeFontProcPtr RealizeFont; + UnrealizeFontProcPtr UnrealizeFont; + + /* Cursor Procedures */ + + ConstrainCursorProcPtr ConstrainCursor; + ConstrainCursorHarderProcPtr ConstrainCursorHarder; + CursorLimitsProcPtr CursorLimits; + DisplayCursorProcPtr DisplayCursor; + RealizeCursorProcPtr RealizeCursor; + UnrealizeCursorProcPtr UnrealizeCursor; + RecolorCursorProcPtr RecolorCursor; + SetCursorPositionProcPtr SetCursorPosition; + + /* GC procedures */ + + CreateGCProcPtr CreateGC; + + /* Colormap procedures */ + + CreateColormapProcPtr CreateColormap; + DestroyColormapProcPtr DestroyColormap; + InstallColormapProcPtr InstallColormap; + UninstallColormapProcPtr UninstallColormap; + ListInstalledColormapsProcPtr ListInstalledColormaps; + StoreColorsProcPtr StoreColors; + ResolveColorProcPtr ResolveColor; + + /* Region procedures */ + + BitmapToRegionProcPtr BitmapToRegion; + SendGraphicsExposeProcPtr SendGraphicsExpose; + + /* os layer procedures */ + + ScreenBlockHandlerProcPtr BlockHandler; + ScreenWakeupHandlerProcPtr WakeupHandler; + + pointer blockData; + pointer wakeupData; + + /* anybody can get a piece of this array */ + PrivateRec *devPrivates; + + CreateScreenResourcesProcPtr CreateScreenResources; + ModifyPixmapHeaderProcPtr ModifyPixmapHeader; + + GetWindowPixmapProcPtr GetWindowPixmap; + SetWindowPixmapProcPtr SetWindowPixmap; + GetScreenPixmapProcPtr GetScreenPixmap; + SetScreenPixmapProcPtr SetScreenPixmap; + + PixmapPtr pScratchPixmap; /* scratch pixmap "pool" */ + + unsigned int totalPixmapSize; + + MarkWindowProcPtr MarkWindow; + MarkOverlappedWindowsProcPtr MarkOverlappedWindows; + ConfigNotifyProcPtr ConfigNotify; + MoveWindowProcPtr MoveWindow; + ResizeWindowProcPtr ResizeWindow; + GetLayerWindowProcPtr GetLayerWindow; + HandleExposuresProcPtr HandleExposures; + ReparentWindowProcPtr ReparentWindow; + + SetShapeProcPtr SetShape; + + ChangeBorderWidthProcPtr ChangeBorderWidth; + MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; + + /* Device cursor procedures */ + DeviceCursorInitializeProcPtr DeviceCursorInitialize; + DeviceCursorCleanupProcPtr DeviceCursorCleanup; + + /* set it in driver side if X server can copy the framebuffer content. + * Meant to be used together with '-background none' option, avoiding + * malicious users to steal framebuffer's content if that would be the + * default */ + Bool canDoBGNoneRoot; +} ScreenRec; + +static inline RegionPtr BitmapToRegion(ScreenPtr _pScreen, PixmapPtr pPix) { + return (*(_pScreen)->BitmapToRegion)(pPix); /* no mi version?! */ +} + +typedef struct _ScreenInfo { + int imageByteOrder; + int bitmapScanlineUnit; + int bitmapScanlinePad; + int bitmapBitOrder; + int numPixmapFormats; + PixmapFormatRec + formats[MAXFORMATS]; + int numScreens; + ScreenPtr screens[MAXSCREENS]; +} ScreenInfo; + +extern _X_EXPORT ScreenInfo screenInfo; + +extern _X_EXPORT void InitOutput( + ScreenInfo * /*pScreenInfo*/, + int /*argc*/, + char ** /*argv*/); + +#endif /* SCREENINTSTRUCT_H */ diff --git a/xorg-server/manpages.am b/xorg-server/manpages.am new file mode 100644 index 000000000..69ee0054d --- /dev/null +++ b/xorg-server/manpages.am @@ -0,0 +1,37 @@ +appmandir = $(APP_MAN_DIR) +#appman_PRE = list of application man page files set by calling Makefile.am +appman_DATA = $(appman_PRE:man=$(APP_MAN_SUFFIX)) + +drivermandir = $(DRIVER_MAN_DIR) +#driverman_PRE = list of driver man page files set by calling Makefile.am +driverman_DATA = $(driverman_PRE:man=$(DRIVER_MAN_SUFFIX)) + +filemandir = $(FILE_MAN_DIR) +#fileman_PRE = list of file man page files set by calling Makefile.am +fileman_DATA = $(fileman_PRE:man=$(FILE_MAN_SUFFIX)) + +# The calling Makefile should only contain man page targets +# Otherwise the following three global variables may conflict +EXTRA_DIST = $(appman_PRE) $(driverman_PRE) $(fileman_PRE) +CLEANFILES = $(appman_DATA) $(driverman_DATA) $(fileman_DATA) +SUFFIXES = .$(APP_MAN_SUFFIX) .$(DRIVER_MAN_SUFFIX) .$(FILE_MAN_SUFFIX) .man + +# Add server specific man pages string substitution from XORG_MANPAGE_SECTIONS +# 's|/,|/, |g' will add a space to help font path formatting +MAN_SUBSTS += -e 's|__logdir__|$(logdir)|g' \ + -e 's|__datadir__|$(datadir)|g' \ + -e 's|__mandir__|$(mandir)|g' \ + -e 's|__sysconfdir__|$(sysconfdir)|g' \ + -e 's|__xconfigdir__|$(__XCONFIGDIR__)|g' \ + -e 's|__xkbdir__|$(XKB_BASE_DIRECTORY)|g' \ + -e 's|__laucnd_id_prefix__|$(LAUNCHD_ID_PREFIX)|g' \ + -e 's|__modulepath__|$(DEFAULT_MODULE_PATH)|g' \ + -e 's|__default_font_path__|$(COMPILEDDEFAULTFONTPATH)|g' \ + -e '\|$(COMPILEDDEFAULTFONTPATH)| s|/,|/, |g' + +.man.$(APP_MAN_SUFFIX): + $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ +.man.$(DRIVER_MAN_SUFFIX): + $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ +.man.$(FILE_MAN_SUFFIX): + $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ diff --git a/xorg-server/xkb/ddxLoad.c b/xorg-server/xkb/ddxLoad.c index cde181c64..51b577725 100644 --- a/xorg-server/xkb/ddxLoad.c +++ b/xorg-server/xkb/ddxLoad.c @@ -1,463 +1,459 @@ -/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <xkb-config.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <X11/X.h>
-#include <X11/Xos.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XKM.h>
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-#include <X11/extensions/XI.h>
-#include "xkb.h"
-
-#if defined(CSRG_BASED) || defined(linux) || defined(__GNU__)
-#include <paths.h>
-#endif
-
- /*
- * If XKM_OUTPUT_DIR specifies a path without a leading slash, it is
- * relative to the top-level XKB configuration directory.
- * Making the server write to a subdirectory of that directory
- * requires some work in the general case (install procedure
- * has to create links to /var or somesuch on many machines),
- * so we just compile into /usr/tmp for now.
- */
-#ifndef XKM_OUTPUT_DIR
-#define XKM_OUTPUT_DIR "compiled/"
-#endif
-
-#define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\""
-#define ERROR_PREFIX "\"> \""
-#define POST_ERROR_MSG1 "\"Errors from xkbcomp are not fatal to the X server\""
-#define POST_ERROR_MSG2 "\"End of messages from xkbcomp\""
-
-#if defined(WIN32)
-#define PATHSEPARATOR "\\"
-#else
-#define PATHSEPARATOR "/"
-#endif
-
-#ifdef WIN32
-
-#include <X11/Xwindows.h>
-const char*
-Win32TempDir()
-{
- static char buffer[PATH_MAX];
- if (GetTempPath(sizeof(buffer), buffer))
- {
- int len;
- buffer[sizeof(buffer)-1] = 0;
- len = strlen(buffer);
- if (len > 0)
- if (buffer[len-1] == '\\')
- buffer[len-1] = 0;
- return buffer;
- }
- if (getenv("TEMP") != NULL)
- return getenv("TEMP");
- else if (getenv("TMP") != NULL)
- return getenv("TEMP");
- else
- return "/tmp";
-}
-
-int
-Win32System(const char *cmdline)
-{
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- DWORD dwExitCode;
- char *cmd = strdup(cmdline);
-
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory( &pi, sizeof(pi) );
-
- if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
- {
- LPVOID buffer;
- if (!FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &buffer,
- 0,
- NULL ))
- {
- ErrorF("[xkb] Starting '%s' failed!\n", cmdline);
- }
- else
- {
- ErrorF("[xkb] Starting '%s' failed: %s", cmdline, (char *)buffer);
- LocalFree(buffer);
- }
-
- free(cmd);
- return -1;
- }
- /* Wait until child process exits. */
- WaitForSingleObject( pi.hProcess, INFINITE );
-
- GetExitCodeProcess( pi.hProcess, &dwExitCode);
-
- /* Close process and thread handles. */
- CloseHandle( pi.hProcess );
- CloseHandle( pi.hThread );
- free(cmd);
-
- return dwExitCode;
-}
-#undef System
-#define System(x) Win32System(x)
-#endif
-
-static void
-OutputDirectory(
- char* outdir,
- size_t size)
-{
-#ifndef WIN32
- /* Can we write an xkm and then open it too? */
- if (access(XKM_OUTPUT_DIR, W_OK | X_OK) == 0 && (strlen(XKM_OUTPUT_DIR) < size))
- {
- (void) strcpy (outdir, XKM_OUTPUT_DIR);
- } else
-#else
- if (strlen(Win32TempDir()) + 1 < size)
- {
- (void) strcpy(outdir, Win32TempDir());
- (void) strcat(outdir, "\\");
- } else
-#endif
- if (strlen("/tmp/") < size)
- {
- (void) strcpy (outdir, "/tmp/");
- }
-}
-
-static Bool
-XkbDDXCompileKeymapByNames( XkbDescPtr xkb,
- XkbComponentNamesPtr names,
- unsigned want,
- unsigned need,
- char * nameRtrn,
- int nameRtrnLen)
-{
- FILE * out;
- char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
-
- const char *emptystring = "";
- char *xkbbasedirflag = NULL;
- const char *xkbbindir = emptystring;
- const char *xkbbindirsep = emptystring;
-
-#ifdef WIN32
- /* WIN32 has no popen. The input must be stored in a file which is
- used as input for xkbcomp. xkbcomp does not read from stdin. */
- char tmpname[PATH_MAX];
- const char *xkmfile = tmpname;
-#else
- const char *xkmfile = "-";
-#endif
-
- snprintf(keymap, sizeof(keymap), "server-%s", display);
-
- OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
-
-#ifdef WIN32
- strcpy(tmpname, Win32TempDir());
- strcat(tmpname, "\\xkb_XXXXXX");
- (void) mktemp(tmpname);
-#endif
-
- if (XkbBaseDirectory != NULL) {
- if (asprintf(&xkbbasedirflag, "\"-R%s\"", XkbBaseDirectory) == -1)
- xkbbasedirflag = NULL;
- }
-
- if (XkbBinDirectory != NULL) {
- int ld = strlen(XkbBinDirectory);
- int lps = strlen(PATHSEPARATOR);
-
- xkbbindir = XkbBinDirectory;
-
- if ((ld >= lps) &&
- (strcmp(xkbbindir + ld - lps, PATHSEPARATOR) != 0)) {
- xkbbindirsep = PATHSEPARATOR;
- }
- }
-
- if (asprintf(&buf,
- "\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" "
- "-em1 %s -emp %s -eml %s \"%s%s.xkm\"",
- xkbbindir, xkbbindirsep,
- ((xkbDebugFlags < 2) ? 1 :
- ((xkbDebugFlags > 10) ? 10 : (int) xkbDebugFlags)),
- xkbbasedirflag ? xkbbasedirflag : "", xkmfile,
- PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1,
- xkm_output_dir, keymap) == -1)
- buf = NULL;
-
- free(xkbbasedirflag);
-
- if (!buf) {
- LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp: not enough memory\n");
- return FALSE;
- }
-
-#ifndef WIN32
- out= Popen(buf,"w");
-#else
- out= fopen(tmpname, "w");
-#endif
-
- if (out!=NULL) {
-#ifdef DEBUG
- if (xkbDebugFlags) {
- ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
- XkbWriteXKBKeymapForNames(stderr,names,xkb,want,need);
- }
-#endif
- XkbWriteXKBKeymapForNames(out,names,xkb,want,need);
-#ifndef WIN32
- if (Pclose(out)==0)
-#else
- if (fclose(out)==0 && System(buf) >= 0)
-#endif
- {
- if (xkbDebugFlags)
- DebugF("[xkb] xkb executes: %s\n",buf);
- if (nameRtrn) {
- strncpy(nameRtrn,keymap,nameRtrnLen);
- nameRtrn[nameRtrnLen-1]= '\0';
- }
- free(buf);
- return TRUE;
- }
- else
- LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
-#ifdef WIN32
- /* remove the temporary file */
- unlink(tmpname);
-#endif
- }
- else {
-#ifndef WIN32
- LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n");
-#else
- LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
-#endif
- }
- if (nameRtrn)
- nameRtrn[0]= '\0';
- free(buf);
- return FALSE;
-}
-
-static FILE *
-XkbDDXOpenConfigFile(char *mapName,char *fileNameRtrn,int fileNameRtrnLen)
-{
-char buf[PATH_MAX],xkm_output_dir[PATH_MAX];
-FILE * file;
-
- buf[0]= '\0';
- if (mapName!=NULL) {
- OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
- if ((XkbBaseDirectory!=NULL)&&(xkm_output_dir[0]!='/')
-#ifdef WIN32
- &&(!isalpha(xkm_output_dir[0]) || xkm_output_dir[1]!=':')
-#endif
- ) {
- if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir)
- +strlen(mapName)+6 <= PATH_MAX)
- {
- sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory,
- xkm_output_dir,mapName);
- }
- }
- else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX)
- sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName);
- if (buf[0] != '\0')
- file= fopen(buf,"rb");
- else file= NULL;
- }
- else file= NULL;
- if ((fileNameRtrn!=NULL)&&(fileNameRtrnLen>0)) {
- strncpy(fileNameRtrn,buf,fileNameRtrnLen);
- buf[fileNameRtrnLen-1]= '\0';
- }
- return file;
-}
-
-unsigned
-XkbDDXLoadKeymapByNames( DeviceIntPtr keybd,
- XkbComponentNamesPtr names,
- unsigned want,
- unsigned need,
- XkbDescPtr * xkbRtrn,
- char * nameRtrn,
- int nameRtrnLen)
-{
-XkbDescPtr xkb;
-FILE * file;
-char fileName[PATH_MAX];
-unsigned missing;
-
- *xkbRtrn = NULL;
- if ((keybd==NULL)||(keybd->key==NULL)||(keybd->key->xkbInfo==NULL))
- xkb= NULL;
- else xkb= keybd->key->xkbInfo->desc;
- if ((names->keycodes==NULL)&&(names->types==NULL)&&
- (names->compat==NULL)&&(names->symbols==NULL)&&
- (names->geometry==NULL)) {
- LogMessage(X_ERROR, "XKB: No components provided for device %s\n",
- keybd->name ? keybd->name : "(unnamed keyboard)");
- return 0;
- }
- else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need,
- nameRtrn,nameRtrnLen)){
- LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
- return 0;
- }
- file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX);
- if (file==NULL) {
- LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",fileName);
- return 0;
- }
- missing= XkmReadFile(file,need,want,xkbRtrn);
- if (*xkbRtrn==NULL) {
- LogMessage(X_ERROR, "Error loading keymap %s\n",fileName);
- fclose(file);
- (void) unlink (fileName);
- return 0;
- }
- else {
- DebugF("Loaded XKB keymap %s, defined=0x%x\n",fileName,(*xkbRtrn)->defined);
- }
- fclose(file);
- (void) unlink (fileName);
- return (need|want)&(~missing);
-}
-
-Bool
-XkbDDXNamesFromRules( DeviceIntPtr keybd,
- char * rules_name,
- XkbRF_VarDefsPtr defs,
- XkbComponentNamesPtr names)
-{
-char buf[PATH_MAX];
-FILE * file;
-Bool complete;
-XkbRF_RulesPtr rules;
-
- if (!rules_name)
- return FALSE;
-
- if (strlen(XkbBaseDirectory) + strlen(rules_name) + 8 > PATH_MAX) {
- LogMessage(X_ERROR, "XKB: Rules name is too long\n");
- return FALSE;
- }
- sprintf(buf,"%s/rules/%s", XkbBaseDirectory, rules_name);
-
- file = fopen(buf, "r");
- if (!file) {
- LogMessage(X_ERROR, "XKB: Couldn't open rules file %s\n", buf);
- return FALSE;
- }
-
- rules = XkbRF_Create();
- if (!rules) {
- LogMessage(X_ERROR, "XKB: Couldn't create rules struct\n");
- fclose(file);
- return FALSE;
- }
-
- if (!XkbRF_LoadRules(file, rules)) {
- LogMessage(X_ERROR, "XKB: Couldn't parse rules file %s\n", rules_name);
- fclose(file);
- XkbRF_Free(rules,TRUE);
- return FALSE;
- }
-
- memset(names, 0, sizeof(*names));
- complete = XkbRF_GetComponents(rules,defs,names);
- fclose(file);
- XkbRF_Free(rules, TRUE);
-
- if (!complete)
- LogMessage(X_ERROR, "XKB: Rules returned no components\n");
-
- return complete;
-}
-
-XkbDescPtr
-XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet *rmlvo)
-{
- XkbComponentNamesRec kccgst;
- XkbRF_VarDefsRec mlvo;
- XkbDescPtr xkb;
- char name[PATH_MAX];
-
- if (!dev || !rmlvo) {
- LogMessage(X_ERROR, "XKB: No device or RMLVO specified\n");
- return NULL;
- }
-
- mlvo.model = rmlvo->model;
- mlvo.layout = rmlvo->layout;
- mlvo.variant = rmlvo->variant;
- mlvo.options = rmlvo->options;
-
- /* XDNFR already logs for us. */
- if (!XkbDDXNamesFromRules(dev, rmlvo->rules, &mlvo, &kccgst))
- return NULL;
-
- /* XDLKBN too, but it might return 0 as well as allocating. */
- if (!XkbDDXLoadKeymapByNames(dev, &kccgst, XkmAllIndicesMask, 0, &xkb, name,
- PATH_MAX)) {
- if (xkb)
- XkbFreeKeyboard(xkb, 0, TRUE);
- return NULL;
- }
-
- return xkb;
-}
+/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <xkb-config.h> + +#include <stdio.h> +#include <ctype.h> +#include <X11/X.h> +#include <X11/Xos.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include <X11/extensions/XKM.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#define XKBSRV_NEED_FILE_FUNCS +#include <xkbsrv.h> +#include <X11/extensions/XI.h> +#include "xkb.h" + + /* + * If XKM_OUTPUT_DIR specifies a path without a leading slash, it is + * relative to the top-level XKB configuration directory. + * Making the server write to a subdirectory of that directory + * requires some work in the general case (install procedure + * has to create links to /var or somesuch on many machines), + * so we just compile into /usr/tmp for now. + */ +#ifndef XKM_OUTPUT_DIR +#define XKM_OUTPUT_DIR "compiled/" +#endif + +#define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\"" +#define ERROR_PREFIX "\"> \"" +#define POST_ERROR_MSG1 "\"Errors from xkbcomp are not fatal to the X server\"" +#define POST_ERROR_MSG2 "\"End of messages from xkbcomp\"" + +#if defined(WIN32) +#define PATHSEPARATOR "\\" +#else +#define PATHSEPARATOR "/" +#endif + +#ifdef WIN32 + +#include <X11/Xwindows.h> +const char* +Win32TempDir() +{ + static char buffer[PATH_MAX]; + if (GetTempPath(sizeof(buffer), buffer)) + { + int len; + buffer[sizeof(buffer)-1] = 0; + len = strlen(buffer); + if (len > 0) + if (buffer[len-1] == '\\') + buffer[len-1] = 0; + return buffer; + } + if (getenv("TEMP") != NULL) + return getenv("TEMP"); + else if (getenv("TMP") != NULL) + return getenv("TEMP"); + else + return "/tmp"; +} + +int +Win32System(const char *cmdline) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + DWORD dwExitCode; + char *cmd = strdup(cmdline); + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + + if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + LPVOID buffer; + if (!FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &buffer, + 0, + NULL )) + { + ErrorF("[xkb] Starting '%s' failed!\n", cmdline); + } + else + { + ErrorF("[xkb] Starting '%s' failed: %s", cmdline, (char *)buffer); + LocalFree(buffer); + } + + free(cmd); + return -1; + } + /* Wait until child process exits. */ + WaitForSingleObject( pi.hProcess, INFINITE ); + + GetExitCodeProcess( pi.hProcess, &dwExitCode); + + /* Close process and thread handles. */ + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + free(cmd); + + return dwExitCode; +} +#undef System +#define System(x) Win32System(x) +#endif + +static void +OutputDirectory( + char* outdir, + size_t size) +{ +#ifndef WIN32 + /* Can we write an xkm and then open it too? */ + if (access(XKM_OUTPUT_DIR, W_OK | X_OK) == 0 && (strlen(XKM_OUTPUT_DIR) < size)) + { + (void) strcpy (outdir, XKM_OUTPUT_DIR); + } else +#else + if (strlen(Win32TempDir()) + 1 < size) + { + (void) strcpy(outdir, Win32TempDir()); + (void) strcat(outdir, "\\"); + } else +#endif + if (strlen("/tmp/") < size) + { + (void) strcpy (outdir, "/tmp/"); + } +} + +static Bool +XkbDDXCompileKeymapByNames( XkbDescPtr xkb, + XkbComponentNamesPtr names, + unsigned want, + unsigned need, + char * nameRtrn, + int nameRtrnLen) +{ + FILE * out; + char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX]; + + const char *emptystring = ""; + char *xkbbasedirflag = NULL; + const char *xkbbindir = emptystring; + const char *xkbbindirsep = emptystring; + +#ifdef WIN32 + /* WIN32 has no popen. The input must be stored in a file which is + used as input for xkbcomp. xkbcomp does not read from stdin. */ + char tmpname[PATH_MAX]; + const char *xkmfile = tmpname; +#else + const char *xkmfile = "-"; +#endif + + snprintf(keymap, sizeof(keymap), "server-%s", display); + + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); + +#ifdef WIN32 + strcpy(tmpname, Win32TempDir()); + strcat(tmpname, "\\xkb_XXXXXX"); + (void) mktemp(tmpname); +#endif + + if (XkbBaseDirectory != NULL) { + if (asprintf(&xkbbasedirflag, "\"-R%s\"", XkbBaseDirectory) == -1) + xkbbasedirflag = NULL; + } + + if (XkbBinDirectory != NULL) { + int ld = strlen(XkbBinDirectory); + int lps = strlen(PATHSEPARATOR); + + xkbbindir = XkbBinDirectory; + + if ((ld >= lps) && + (strcmp(xkbbindir + ld - lps, PATHSEPARATOR) != 0)) { + xkbbindirsep = PATHSEPARATOR; + } + } + + if (asprintf(&buf, + "\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" " + "-em1 %s -emp %s -eml %s \"%s%s.xkm\"", + xkbbindir, xkbbindirsep, + ((xkbDebugFlags < 2) ? 1 : + ((xkbDebugFlags > 10) ? 10 : (int) xkbDebugFlags)), + xkbbasedirflag ? xkbbasedirflag : "", xkmfile, + PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1, + xkm_output_dir, keymap) == -1) + buf = NULL; + + free(xkbbasedirflag); + + if (!buf) { + LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp: not enough memory\n"); + return FALSE; + } + +#ifndef WIN32 + out= Popen(buf,"w"); +#else + out= fopen(tmpname, "w"); +#endif + + if (out!=NULL) { +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n"); + XkbWriteXKBKeymapForNames(stderr,names,xkb,want,need); + } +#endif + XkbWriteXKBKeymapForNames(out,names,xkb,want,need); +#ifndef WIN32 + if (Pclose(out)==0) +#else + if (fclose(out)==0 && System(buf) >= 0) +#endif + { + if (xkbDebugFlags) + DebugF("[xkb] xkb executes: %s\n",buf); + if (nameRtrn) { + strncpy(nameRtrn,keymap,nameRtrnLen); + nameRtrn[nameRtrnLen-1]= '\0'; + } + free(buf); + return TRUE; + } + else + LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap); +#ifdef WIN32 + /* remove the temporary file */ + unlink(tmpname); +#endif + } + else { +#ifndef WIN32 + LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n"); +#else + LogMessage(X_ERROR, "Could not open file %s\n", tmpname); +#endif + } + if (nameRtrn) + nameRtrn[0]= '\0'; + free(buf); + return FALSE; +} + +static FILE * +XkbDDXOpenConfigFile(char *mapName,char *fileNameRtrn,int fileNameRtrnLen) +{ +char buf[PATH_MAX],xkm_output_dir[PATH_MAX]; +FILE * file; + + buf[0]= '\0'; + if (mapName!=NULL) { + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); + if ((XkbBaseDirectory!=NULL)&&(xkm_output_dir[0]!='/') +#ifdef WIN32 + &&(!isalpha(xkm_output_dir[0]) || xkm_output_dir[1]!=':') +#endif + ) { + if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir) + +strlen(mapName)+6 <= PATH_MAX) + { + sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory, + xkm_output_dir,mapName); + } + } + else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX) + sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName); + if (buf[0] != '\0') + file= fopen(buf,"rb"); + else file= NULL; + } + else file= NULL; + if ((fileNameRtrn!=NULL)&&(fileNameRtrnLen>0)) { + strncpy(fileNameRtrn,buf,fileNameRtrnLen); + buf[fileNameRtrnLen-1]= '\0'; + } + return file; +} + +unsigned +XkbDDXLoadKeymapByNames( DeviceIntPtr keybd, + XkbComponentNamesPtr names, + unsigned want, + unsigned need, + XkbDescPtr * xkbRtrn, + char * nameRtrn, + int nameRtrnLen) +{ +XkbDescPtr xkb; +FILE * file; +char fileName[PATH_MAX]; +unsigned missing; + + *xkbRtrn = NULL; + if ((keybd==NULL)||(keybd->key==NULL)||(keybd->key->xkbInfo==NULL)) + xkb= NULL; + else xkb= keybd->key->xkbInfo->desc; + if ((names->keycodes==NULL)&&(names->types==NULL)&& + (names->compat==NULL)&&(names->symbols==NULL)&& + (names->geometry==NULL)) { + LogMessage(X_ERROR, "XKB: No components provided for device %s\n", + keybd->name ? keybd->name : "(unnamed keyboard)"); + return 0; + } + else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need, + nameRtrn,nameRtrnLen)){ + LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n"); + return 0; + } + file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX); + if (file==NULL) { + LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",fileName); + return 0; + } + missing= XkmReadFile(file,need,want,xkbRtrn); + if (*xkbRtrn==NULL) { + LogMessage(X_ERROR, "Error loading keymap %s\n",fileName); + fclose(file); + (void) unlink (fileName); + return 0; + } + else { + DebugF("Loaded XKB keymap %s, defined=0x%x\n",fileName,(*xkbRtrn)->defined); + } + fclose(file); + (void) unlink (fileName); + return (need|want)&(~missing); +} + +Bool +XkbDDXNamesFromRules( DeviceIntPtr keybd, + char * rules_name, + XkbRF_VarDefsPtr defs, + XkbComponentNamesPtr names) +{ +char buf[PATH_MAX]; +FILE * file; +Bool complete; +XkbRF_RulesPtr rules; + + if (!rules_name) + return FALSE; + + if (strlen(XkbBaseDirectory) + strlen(rules_name) + 8 > PATH_MAX) { + LogMessage(X_ERROR, "XKB: Rules name is too long\n"); + return FALSE; + } + sprintf(buf,"%s/rules/%s", XkbBaseDirectory, rules_name); + + file = fopen(buf, "r"); + if (!file) { + LogMessage(X_ERROR, "XKB: Couldn't open rules file %s\n", buf); + return FALSE; + } + + rules = XkbRF_Create(); + if (!rules) { + LogMessage(X_ERROR, "XKB: Couldn't create rules struct\n"); + fclose(file); + return FALSE; + } + + if (!XkbRF_LoadRules(file, rules)) { + LogMessage(X_ERROR, "XKB: Couldn't parse rules file %s\n", rules_name); + fclose(file); + XkbRF_Free(rules,TRUE); + return FALSE; + } + + memset(names, 0, sizeof(*names)); + complete = XkbRF_GetComponents(rules,defs,names); + fclose(file); + XkbRF_Free(rules, TRUE); + + if (!complete) + LogMessage(X_ERROR, "XKB: Rules returned no components\n"); + + return complete; +} + +XkbDescPtr +XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet *rmlvo) +{ + XkbComponentNamesRec kccgst; + XkbRF_VarDefsRec mlvo; + XkbDescPtr xkb; + char name[PATH_MAX]; + + if (!dev || !rmlvo) { + LogMessage(X_ERROR, "XKB: No device or RMLVO specified\n"); + return NULL; + } + + mlvo.model = rmlvo->model; + mlvo.layout = rmlvo->layout; + mlvo.variant = rmlvo->variant; + mlvo.options = rmlvo->options; + + /* XDNFR already logs for us. */ + if (!XkbDDXNamesFromRules(dev, rmlvo->rules, &mlvo, &kccgst)) + return NULL; + + /* XDLKBN too, but it might return 0 as well as allocating. */ + if (!XkbDDXLoadKeymapByNames(dev, &kccgst, XkmAllIndicesMask, 0, &xkb, name, + PATH_MAX)) { + if (xkb) + XkbFreeKeyboard(xkb, 0, TRUE); + return NULL; + } + + return xkb; +} |