+++ /dev/null
-((c-mode . ((c-basic-offset . 3)))
- (c++-mode . ((c-basic-offset . 3)))
-)
+++ /dev/null
-.deps
-COPYING
-INSTALL
-Makefile.in
-aclocal.m4
-autom4te.cache
-config.*
-configure
-depcomp
-ylwrap
-install-sh
-missing
-stamp-h1
-libtool
-ltmain.sh
-Makefile
-*.o
-*~
-glsl_lexer.cpp
-glsl_parser.output
-glsl_parser.cpp
-glsl_parser.h
-glsl
-mesa_codegen.cpp
-mesa_codegen.h
+++ /dev/null
-# Copyright © 2010 Intel Corporation
-# 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
-# on 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
-# AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR 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.
-
-AUTOMAKE_OPTIONS = foreign
-AM_CPPFLAGS = -I mesa
-
-SUBDIRS = glcpp
-
-bin_PROGRAMS = glsl
-
-glsl_LDADD = ./glcpp/libglcpp.la
-glsl_LDFLAGS = @LDFLAGS@ $(talloc_LIBS)
-glsl_SOURCES = \
- main.cpp \
- builtin_types.h \
- symbol_table.c hash_table.c glsl_types.cpp \
- glsl_parser.ypp glsl_lexer.lpp glsl_parser_extras.cpp \
- ast_expr.cpp ast_to_hir.cpp ast_function.cpp ast_type.cpp \
- ir.cpp hir_field_selection.cpp builtin_function.cpp \
- ir_print_visitor.cpp ir_variable.cpp ir_function.cpp \
- ir_basic_block.cpp \
- ir_basic_block.h \
- ir_clone.cpp \
- ir_constant_expression.cpp \
- ir_constant_folding.cpp \
- ir_constant_variable.cpp \
- ir_copy_propagation.cpp \
- ir_copy_propagation.h \
- ir_dead_code.cpp \
- ir_dead_code.h \
- ir_dead_code_local.cpp \
- ir_expression_flattening.cpp \
- ir_function_can_inline.cpp \
- ir_function_inlining.cpp \
- ir_if_simplification.cpp \
- ir_optimization.h \
- ir_reader.cpp s_expression.cpp \
- ir_hv_accept.cpp \
- ir_hierarchical_visitor.h \
- ir_hierarchical_visitor.cpp \
- ir_swizzle_swizzle.cpp \
- ir_to_mesa.cpp \
- ir_to_mesa.h \
- ir_validate.cpp \
- ir_vec_index_to_swizzle.cpp \
- linker.cpp \
- mesa/shader/prog_instruction.c \
- mesa/shader/prog_instruction.h \
- mesa/shader/prog_print.c \
- mesa/shader/prog_print.h
-
-BUILT_SOURCES = glsl_parser.h glsl_parser.cpp glsl_lexer.cpp
-CLEANFILES = $(BUILT_SOURCES)
-
-builtin_function.cpp: builtins/*/*
- ./builtins/tools/generate_builtins.pl > builtin_function.cpp
-glsl_parser.h: glsl_parser.cpp
-
-.lpp.cpp:
- $(LEXCOMPILE) --outfile="$@" $<
+++ /dev/null
-- Implement AST-to-HIR conversion of discard instructions.
-
-- Handle constant expressions of (matrix {+,-,*,/} scalar)
-
-- Handle constant expressions of (vector {+,-,*,/} scalar)
-
-- Handle constant expressions of (matrix * vector)
-
-- Handle constant expressions of (matrix * matrix)
-
-- Handle currently unsupported constant expression types
- - ir_unop_sign
- - ir_unop_exp2
- - ir_unop_log2
- - ir_unop_u2f
- - ir_unop_trunc
- - ir_unop_ceil
- - ir_unop_floor
- - ir_unop_sin
- - ir_unop_cos
- - ir_binop_dot
- - ir_binop_min
- - ir_binop_max
- - ir_binop_pow
-
-- Handle constant expressions of (struct == struct)
-
-- Handle constant expressions of (struct != struct)
-
-- Add support to ir_constant for array constants Arrays can only be
- - declared 'const' in GLSL 1.20+. This is because there are no
- array constructors in GLSL 1.10, and any variable declared as
- 'const' must have an initializer.
-
-- Handle constant expressions of (array == array)
-
-- Handle constant expressions of (array != array)
-
-- Treat built-in functions with constant parameters as constant expressions.
- - Rewrite all built-in functions return a single expression.
- - Modify the HIR generator for functions to automatically inline built-in
- functions durning translation.
- - Care must be taken to handle both the 1.10 rules and the 1.20+ rules. In
- 1.10, built-in functions cannot be constant expressions.
-
-- Detect non-void functions that lack a return statement
-
-- Detect return statements with a type not matching the funciton's
- return type.
-
-- Handle over-riding built-in functions
- - Is the overload per-compilation unit or per-linked shader?
-
-- Handle redeclaration of built-in variables
- - Handle addition of qualifiers such as 'invariant' or 'centroid'.
- - Handle resizing of arrays.
- - Other? We'll have to look at the spec.
-
-- Improve handling of constants and their initializers. Constant initializers
- should never generate any code. This is trival for scalar constants. It is
- also trivial for arrays, matrices, and vectors that are accessed with
- constant index values. For others it is more complicated. Perhaps these
- cases should be silently converted to uniforms?
-
-1.30 features:
-
-- Implement AST-to-HIR conversion of bit-shift operators.
-
-- Implement AST-to-HIR conversion of bit-wise {&,|,^,!} operators.
-
-- Implement AST-to-HIR conversion of switch-statements
- - switch
- - case
- - Update break to correcly handle mixed nexting of switch-statements
- and loops.
-
-- Handle currently unsupported constant expression types
- - ir_unop_bit_not
- - ir_binop_mod
- - ir_binop_lshift
- - ir_binop_rshift
- - ir_binop_bit_and
- - ir_binop_bit_xor
- - ir_binop_bit_or
+++ /dev/null
-/* -*- 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 ir_instruction;
-struct _mesa_glsl_parse_state;
-
-struct YYLTYPE;
-
-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_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);
- }
-
- virtual void print(void) const;
- 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;
- }
-
- struct {
- unsigned source;
- unsigned line;
- unsigned column;
- } location;
-
- exec_node link;
-
-protected:
- ast_node(void);
-};
-
-
-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
-};
-
-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 {
- 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;
-};
-
-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;
-
- 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:
- 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 struct ir_rvalue *
-_mesa_ast_field_selection_to_hir(const struct ast_expression *expr,
- exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
-#endif /* AST_H */
+++ /dev/null
-/*
- * 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 <cassert>
-#include "ast.h"
-
-const char *
-ast_expression::operator_string(enum ast_operators op)
-{
- static const char *const operators[] = {
- "=",
- "+",
- "-",
- "+",
- "-",
- "*",
- "/",
- "%",
- "<<",
- ">>",
- "<",
- ">",
- "<=",
- ">=",
- "==",
- "!=",
- "&",
- "^",
- "|",
- "~",
- "&&",
- "^^",
- "||",
- "!",
-
- "*=",
- "/=",
- "%=",
- "+=",
- "-=",
- "<<=",
- ">>=",
- "&=",
- "^=",
- "|=",
-
- "?:",
-
- "++",
- "--",
- "++",
- "--",
- ".",
- };
-
- assert((unsigned int)op < sizeof(operators) / sizeof(operators[0]));
-
- return operators[op];
-}
-
-
-ast_expression_bin::ast_expression_bin(int oper, ast_expression *ex0,
- ast_expression *ex1) :
- ast_expression(oper, ex0, ex1, NULL)
-{
- assert((oper >= ast_plus) && (oper <= ast_logic_not));
-}
-
-
-void
-ast_expression_bin::print(void) const
-{
- subexpressions[0]->print();
- printf("%s ", operator_string(oper));
- subexpressions[1]->print();
-}
+++ /dev/null
-/*
- * 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_symbol_table.h"
-#include "ast.h"
-#include "glsl_types.h"
-#include "ir.h"
-
-static unsigned
-process_parameters(exec_list *instructions, exec_list *actual_parameters,
- exec_list *parameters,
- struct _mesa_glsl_parse_state *state)
-{
- unsigned count = 0;
-
- foreach_list (n, parameters) {
- ast_node *const ast = exec_node_data(ast_node, n, link);
- ir_rvalue *result = ast->hir(instructions, state);
-
- ir_constant *const constant = result->constant_expression_value();
- if (constant != NULL)
- result = constant;
-
- actual_parameters->push_tail(result);
- count++;
- }
-
- return count;
-}
-
-
-static ir_rvalue *
-process_call(exec_list *instructions, ir_function *f,
- YYLTYPE *loc, exec_list *actual_parameters,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
-
- const ir_function_signature *sig =
- f->matching_signature(actual_parameters);
-
- /* The instructions param will be used when the FINISHMEs below are done */
- (void) instructions;
-
- if (sig != NULL) {
- /* Verify that 'out' and 'inout' actual parameters are lvalues. This
- * isn't done in ir_function::matching_signature because that function
- * cannot generate the necessary diagnostics.
- */
- exec_list_iterator actual_iter = actual_parameters->iterator();
- exec_list_iterator formal_iter = sig->parameters.iterator();
-
- while (actual_iter.has_next()) {
- ir_rvalue *actual = (ir_rvalue *) actual_iter.get();
- ir_variable *formal = (ir_variable *) formal_iter.get();
-
- assert(actual != NULL);
- assert(formal != NULL);
-
- if ((formal->mode == ir_var_out)
- || (formal->mode == ir_var_inout)) {
- if (! actual->is_lvalue()) {
- /* FINISHME: Log a better diagnostic here. There is no way
- * FINISHME: to tell the user which parameter is invalid.
- */
- _mesa_glsl_error(loc, state, "`%s' parameter is not lvalue",
- (formal->mode == ir_var_out) ? "out" : "inout");
- }
- }
-
- actual_iter.next();
- formal_iter.next();
- }
-
- /* FINISHME: The list of actual parameters needs to be modified to
- * FINISHME: include any necessary conversions.
- */
- return new(ctx) ir_call(sig, actual_parameters);
- } else {
- /* FINISHME: Log a better error message here. G++ will show the types
- * FINISHME: of the actual parameters and the set of candidate
- * FINISHME: functions. A different error should also be logged when
- * FINISHME: multiple functions match.
- */
- _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
- f->name);
- return ir_call::get_error_instruction(ctx);
- }
-}
-
-
-static ir_rvalue *
-match_function_by_name(exec_list *instructions, const char *name,
- YYLTYPE *loc, exec_list *actual_parameters,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- ir_function *f = state->symbols->get_function(name);
-
- if (f == NULL) {
- _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
- return ir_call::get_error_instruction(ctx);
- }
-
- /* Once we've determined that the function being called might exist, try
- * to find an overload of the function that matches the parameters.
- */
- return process_call(instructions, f, loc, actual_parameters, state);
-}
-
-
-/**
- * Perform automatic type conversion of constructor parameters
- */
-static ir_rvalue *
-convert_component(ir_rvalue *src, const glsl_type *desired_type)
-{
- void *ctx = talloc_parent(src);
- const unsigned a = desired_type->base_type;
- const unsigned b = src->type->base_type;
- ir_expression *result = NULL;
-
- if (src->type->is_error())
- return src;
-
- assert(a <= GLSL_TYPE_BOOL);
- assert(b <= GLSL_TYPE_BOOL);
-
- if ((a == b) || (src->type->is_integer() && desired_type->is_integer()))
- return src;
-
- switch (a) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- if (b == GLSL_TYPE_FLOAT)
- result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL);
- else {
- assert(b == GLSL_TYPE_BOOL);
- result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL);
- }
- break;
- case GLSL_TYPE_FLOAT:
- switch (b) {
- case GLSL_TYPE_UINT:
- result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL);
- break;
- case GLSL_TYPE_INT:
- result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL);
- break;
- case GLSL_TYPE_BOOL:
- result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL);
- break;
- }
- break;
- case GLSL_TYPE_BOOL: {
- ir_constant *zero = NULL;
-
- switch (b) {
- case GLSL_TYPE_UINT: zero = new(ctx) ir_constant(unsigned(0)); break;
- case GLSL_TYPE_INT: zero = new(ctx) ir_constant(int(0)); break;
- case GLSL_TYPE_FLOAT: zero = new(ctx) ir_constant(0.0f); break;
- }
-
- result = new(ctx) ir_expression(ir_binop_nequal, desired_type, src, zero);
- }
- }
-
- assert(result != NULL);
-
- ir_constant *const constant = result->constant_expression_value();
- return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result;
-}
-
-
-/**
- * Dereference a specific component from a scalar, vector, or matrix
- */
-static ir_rvalue *
-dereference_component(ir_rvalue *src, unsigned component)
-{
- void *ctx = talloc_parent(src);
- assert(component < src->type->components());
-
- /* If the source is a constant, just create a new constant instead of a
- * dereference of the existing constant.
- */
- ir_constant *constant = src->as_constant();
- if (constant)
- return new(ctx) ir_constant(constant, component);
-
- if (src->type->is_scalar()) {
- return src;
- } else if (src->type->is_vector()) {
- return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1);
- } else {
- assert(src->type->is_matrix());
-
- /* Dereference a row of the matrix, then call this function again to get
- * a specific element from that row.
- */
- const int c = component / src->type->column_type()->vector_elements;
- const int r = component % src->type->column_type()->vector_elements;
- ir_constant *const col_index = new(ctx) ir_constant(c);
- ir_dereference *const col = new(ctx) ir_dereference_array(src, col_index);
-
- col->type = src->type->column_type();
-
- return dereference_component(col, r);
- }
-
- assert(!"Should not get here.");
- return NULL;
-}
-
-
-static ir_rvalue *
-process_array_constructor(exec_list *instructions,
- const glsl_type *constructor_type,
- YYLTYPE *loc, exec_list *parameters,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- /* Array constructors come in two forms: sized and unsized. Sized array
- * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4
- * variables. In this case the number of parameters must exactly match the
- * specified size of the array.
- *
- * Unsized array constructors look like 'vec4[](a, b)', where 'a' and 'b'
- * are vec4 variables. In this case the size of the array being constructed
- * is determined by the number of parameters.
- *
- * From page 52 (page 58 of the PDF) of the GLSL 1.50 spec:
- *
- * "There must be exactly the same number of arguments as the size of
- * the array being constructed. If no size is present in the
- * constructor, then the array is explicitly sized to the number of
- * arguments provided. The arguments are assigned in order, starting at
- * element 0, to the elements of the constructed array. Each argument
- * must be the same type as the element type of the array, or be a type
- * that can be converted to the element type of the array according to
- * Section 4.1.10 "Implicit Conversions.""
- */
- exec_list actual_parameters;
- const unsigned parameter_count =
- process_parameters(instructions, &actual_parameters, parameters, state);
-
- if ((parameter_count == 0)
- || ((constructor_type->length != 0)
- && (constructor_type->length != parameter_count))) {
- const unsigned min_param = (constructor_type->length == 0)
- ? 1 : constructor_type->length;
-
- _mesa_glsl_error(loc, state, "array constructor must have %s %u "
- "parameter%s",
- (constructor_type->length != 0) ? "at least" : "exactly",
- min_param, (min_param <= 1) ? "" : "s");
- return ir_call::get_error_instruction(ctx);
- }
-
- if (constructor_type->length == 0) {
- constructor_type =
- glsl_type::get_array_instance(state,
- constructor_type->element_type(),
- parameter_count);
- assert(constructor_type != NULL);
- assert(constructor_type->length == parameter_count);
- }
-
- ir_function *f = state->symbols->get_function(constructor_type->name);
-
- /* If the constructor for this type of array does not exist, generate the
- * prototype and add it to the symbol table.
- */
- if (f == NULL) {
- f = constructor_type->generate_constructor(state->symbols);
- }
-
- ir_rvalue *const r =
- process_call(instructions, f, loc, &actual_parameters, state);
-
- assert(r != NULL);
- assert(r->type->is_error() || (r->type == constructor_type));
-
- return r;
-}
-
-
-/**
- * Try to convert a record constructor to a constant expression
- */
-static ir_constant *
-constant_record_constructor(const glsl_type *constructor_type,
- YYLTYPE *loc, exec_list *parameters,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- bool all_parameters_are_constant = true;
-
- exec_node *node = parameters->head;
- for (unsigned i = 0; i < constructor_type->length; i++) {
- ir_instruction *ir = (ir_instruction *) node;
-
- if (node->is_tail_sentinal()) {
- _mesa_glsl_error(loc, state,
- "insufficient parameters to constructor for `%s'",
- constructor_type->name);
- return NULL;
- }
-
- if (ir->type != constructor_type->fields.structure[i].type) {
- _mesa_glsl_error(loc, state,
- "parameter type mismatch in constructor for `%s' "
- " (%s vs %s)",
- constructor_type->name,
- ir->type->name,
- constructor_type->fields.structure[i].type->name);
- return NULL;
- }
-
- if (ir->as_constant() == NULL)
- all_parameters_are_constant = false;
-
- node = node->next;
- }
-
- if (!all_parameters_are_constant)
- return NULL;
-
- return new(ctx) ir_constant(constructor_type, parameters);
-}
-
-
-/**
- * Generate data for a constant matrix constructor w/a single scalar parameter
- *
- * Matrix constructors in GLSL can be passed a single scalar of the
- * approriate type. In these cases, the resulting matrix is the identity
- * matrix multipled by the specified scalar. This function generates data for
- * that matrix.
- *
- * \param type Type of the desired matrix.
- * \param initializer Scalar value used to initialize the matrix diagonal.
- * \param data Location to store the resulting matrix.
- */
-void
-generate_constructor_matrix(const glsl_type *type, ir_constant *initializer,
- ir_constant_data *data)
-{
- switch (type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- for (unsigned i = 0; i < type->components(); i++)
- data->u[i] = 0;
-
- for (unsigned i = 0; i < type->matrix_columns; i++) {
- /* The array offset of the ith row and column of the matrix.
- */
- const unsigned idx = (i * type->vector_elements) + i;
-
- data->u[idx] = initializer->value.u[0];
- }
- break;
-
- case GLSL_TYPE_FLOAT:
- for (unsigned i = 0; i < type->components(); i++)
- data->f[i] = 0;
-
- for (unsigned i = 0; i < type->matrix_columns; i++) {
- /* The array offset of the ith row and column of the matrix.
- */
- const unsigned idx = (i * type->vector_elements) + i;
-
- data->f[idx] = initializer->value.f[0];
- }
-
- break;
-
- default:
- assert(!"Should not get here.");
- break;
- }
-}
-
-
-/**
- * Generate data for a constant vector constructor w/a single scalar parameter
- *
- * Vector constructors in GLSL can be passed a single scalar of the
- * approriate type. In these cases, the resulting vector contains the specified
- * value in all components. This function generates data for that vector.
- *
- * \param type Type of the desired vector.
- * \param initializer Scalar value used to initialize the vector.
- * \param data Location to store the resulting vector data.
- */
-void
-generate_constructor_vector(const glsl_type *type, ir_constant *initializer,
- ir_constant_data *data)
-{
- switch (type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- for (unsigned i = 0; i < type->components(); i++)
- data->u[i] = initializer->value.u[0];
-
- break;
-
- case GLSL_TYPE_FLOAT:
- for (unsigned i = 0; i < type->components(); i++)
- data->f[i] = initializer->value.f[0];
-
- break;
-
- case GLSL_TYPE_BOOL:
- for (unsigned i = 0; i < type->components(); i++)
- data->b[i] = initializer->value.b[0];
-
- break;
-
- default:
- assert(!"Should not get here.");
- break;
- }
-}
-
-
-ir_rvalue *
-ast_function_expression::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- /* There are three sorts of function calls.
- *
- * 1. contstructors - The first subexpression is an ast_type_specifier.
- * 2. methods - Only the .length() method of array types.
- * 3. functions - Calls to regular old functions.
- *
- * Method calls are actually detected when the ast_field_selection
- * expression is handled.
- */
- if (is_constructor()) {
- const ast_type_specifier *type = (ast_type_specifier *) subexpressions[0];
- YYLTYPE loc = type->get_location();
- const char *name;
-
- const glsl_type *const constructor_type = type->glsl_type(& name, state);
-
-
- /* Constructors for samplers are illegal.
- */
- if (constructor_type->is_sampler()) {
- _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- if (constructor_type->is_array()) {
- if (state->language_version <= 110) {
- _mesa_glsl_error(& loc, state,
- "array constructors forbidden in GLSL 1.10");
- return ir_call::get_error_instruction(ctx);
- }
-
- return process_array_constructor(instructions, constructor_type,
- & loc, &this->expressions, state);
- }
-
- /* There are two kinds of constructor call. Constructors for built-in
- * language types, such as mat4 and vec2, are free form. The only
- * requirement is that the parameters must provide enough values of the
- * correct scalar type. Constructors for arrays and structures must
- * have the exact number of parameters with matching types in the
- * correct order. These constructors follow essentially the same type
- * matching rules as functions.
- */
- if (constructor_type->is_numeric() || constructor_type->is_boolean()) {
- /* Constructing a numeric type has a couple steps. First all values
- * passed to the constructor are broken into individual parameters
- * and type converted to the base type of the thing being constructed.
- *
- * At that point we have some number of values that match the base
- * type of the thing being constructed. Now the constructor can be
- * treated like a function call. Each numeric type has a small set
- * of constructor functions. The set of new parameters will either
- * match one of those functions or the original constructor is
- * invalid.
- */
- const glsl_type *const base_type = constructor_type->get_base_type();
-
- /* Total number of components of the type being constructed.
- */
- const unsigned type_components = constructor_type->components();
-
- /* Number of components from parameters that have actually been
- * consumed. This is used to perform several kinds of error checking.
- */
- unsigned components_used = 0;
-
- unsigned matrix_parameters = 0;
- unsigned nonmatrix_parameters = 0;
- exec_list actual_parameters;
-
- bool all_parameters_are_constant = true;
-
- /* This handles invalid constructor calls such as 'vec4 v = vec4();'
- */
- if (this->expressions.is_empty()) {
- _mesa_glsl_error(& loc, state, "too few components to construct "
- "`%s'",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- foreach_list (n, &this->expressions) {
- ast_node *ast = exec_node_data(ast_node, n, link);
- ir_rvalue *result =
- ast->hir(instructions, state)->as_rvalue();
- ir_variable *result_var = NULL;
-
- /* Attempt to convert the parameter to a constant valued expression.
- * After doing so, track whether or not all the parameters to the
- * constructor are trivially constant valued expressions.
- */
- ir_rvalue *const constant =
- result->constant_expression_value();
-
- if (constant != NULL)
- result = constant;
- else
- all_parameters_are_constant = false;
-
- /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
- *
- * "It is an error to provide extra arguments beyond this
- * last used argument."
- */
- if (components_used >= type_components) {
- _mesa_glsl_error(& loc, state, "too many parameters to `%s' "
- "constructor",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- if (!result->type->is_numeric() && !result->type->is_boolean()) {
- _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
- "non-numeric data type",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- /* Count the number of matrix and nonmatrix parameters. This
- * is used below to enforce some of the constructor rules.
- */
- if (result->type->is_matrix())
- matrix_parameters++;
- else
- nonmatrix_parameters++;
-
- /* We can't use the same instruction node in the multiple
- * swizzle dereferences that happen, so assign it to a
- * variable and deref that. Plus it saves computation for
- * complicated expressions and handles
- * glsl-vs-constructor-call.shader_test.
- */
- if (result->type->components() >= 1 && !result->as_constant()) {
- result_var = new(ctx) ir_variable(result->type,
- "constructor_tmp");
- ir_dereference_variable *lhs;
-
- lhs = new(ctx) ir_dereference_variable(result_var);
- instructions->push_tail(new(ctx) ir_assignment(lhs,
- result, NULL));
- }
-
- /* Process each of the components of the parameter. Dereference
- * each component individually, perform any type conversions, and
- * add it to the parameter list for the constructor.
- */
- for (unsigned i = 0; i < result->type->components(); i++) {
- if (components_used >= type_components)
- break;
-
- ir_rvalue *component;
-
- if (result_var) {
- ir_dereference *d = new(ctx) ir_dereference_variable(result_var);
- component = dereference_component(d, i);
- } else {
- component = dereference_component(result, i);
- }
- component = convert_component(component, base_type);
-
- /* All cases that could result in component->type being the
- * error type should have already been caught above.
- */
- assert(component->type == base_type);
-
- if (component->as_constant() == NULL)
- all_parameters_are_constant = false;
-
- /* Don't actually generate constructor calls for scalars.
- * Instead, do the usual component selection and conversion,
- * and return the single component.
- */
- if (constructor_type->is_scalar())
- return component;
-
- actual_parameters.push_tail(component);
- components_used++;
- }
- }
-
- /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
- *
- * "It is an error to construct matrices from other matrices. This
- * is reserved for future use."
- */
- if ((state->language_version <= 110) && (matrix_parameters > 0)
- && constructor_type->is_matrix()) {
- _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
- "matrix in GLSL 1.10",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
- *
- * "If a matrix argument is given to a matrix constructor, it is
- * an error to have any other arguments."
- */
- if ((matrix_parameters > 0)
- && ((matrix_parameters + nonmatrix_parameters) > 1)
- && constructor_type->is_matrix()) {
- _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
- "matrix must be only parameter",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
- *
- * "In these cases, there must be enough components provided in the
- * arguments to provide an initializer for every component in the
- * constructed value."
- */
- if ((components_used < type_components) && (components_used != 1)) {
- _mesa_glsl_error(& loc, state, "too few components to construct "
- "`%s'",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- ir_function *f = state->symbols->get_function(constructor_type->name);
- if (f == NULL) {
- _mesa_glsl_error(& loc, state, "no constructor for type `%s'",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- const ir_function_signature *sig =
- f->matching_signature(& actual_parameters);
- if (sig != NULL) {
- /* If all of the parameters are trivially constant, create a
- * constant representing the complete collection of parameters.
- */
- if (all_parameters_are_constant) {
- if (components_used >= type_components)
- return new(ctx) ir_constant(sig->return_type,
- & actual_parameters);
-
- assert(sig->return_type->is_vector()
- || sig->return_type->is_matrix());
-
- /* Constructors with exactly one component are special for
- * vectors and matrices. For vectors it causes all elements of
- * the vector to be filled with the value. For matrices it
- * causes the matrix to be filled with 0 and the diagonal to be
- * filled with the value.
- */
- ir_constant_data data;
- ir_constant *const initializer =
- (ir_constant *) actual_parameters.head;
- if (sig->return_type->is_matrix())
- generate_constructor_matrix(sig->return_type, initializer,
- &data);
- else
- generate_constructor_vector(sig->return_type, initializer,
- &data);
-
- return new(ctx) ir_constant(sig->return_type, &data);
- } else
- return new(ctx) ir_call(sig, & actual_parameters);
- } else {
- /* FINISHME: Log a better error message here. G++ will show the
- * FINSIHME: types of the actual parameters and the set of
- * FINSIHME: candidate functions. A different error should also be
- * FINSIHME: logged when multiple functions match.
- */
- _mesa_glsl_error(& loc, state, "no matching constructor for `%s'",
- constructor_type->name);
- return ir_call::get_error_instruction(ctx);
- }
- }
-
- return ir_call::get_error_instruction(ctx);
- } else {
- const ast_expression *id = subexpressions[0];
- YYLTYPE loc = id->get_location();
- exec_list actual_parameters;
-
- process_parameters(instructions, &actual_parameters, &this->expressions,
- state);
-
- const glsl_type *const type =
- state->symbols->get_type(id->primary_expression.identifier);
-
- if ((type != NULL) && type->is_record()) {
- ir_constant *constant =
- constant_record_constructor(type, &loc, &actual_parameters, state);
-
- if (constant != NULL)
- return constant;
- }
-
- return match_function_by_name(instructions,
- id->primary_expression.identifier, & loc,
- &actual_parameters, state);
- }
-
- return ir_call::get_error_instruction(ctx);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ast_to_hir.c
- * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
- *
- * During the conversion to HIR, the majority of the symantic checking is
- * preformed on the program. This includes:
- *
- * * Symbol table management
- * * Type checking
- * * Function binding
- *
- * The majority of this work could be done during parsing, and the parser could
- * probably generate HIR directly. However, this results in frequent changes
- * to the parser code. Since we do not assume that every system this complier
- * is built on will have Flex and Bison installed, we have to store the code
- * generated by these tools in our version control system. In other parts of
- * the system we've seen problems where a parser was changed but the generated
- * code was not committed, merge conflicts where created because two developers
- * had slightly different versions of Bison installed, etc.
- *
- * I have also noticed that running Bison generated parsers in GDB is very
- * irritating. When you get a segfault on '$$ = $1->foo', you can't very
- * well 'print $1' in GDB.
- *
- * As a result, my preference is to put as little C code as possible in the
- * parser (and lexer) sources.
- */
-
-#include "main/imports.h"
-#include "glsl_symbol_table.h"
-#include "glsl_parser_extras.h"
-#include "ast.h"
-#include "glsl_types.h"
-#include "ir.h"
-
-void
-_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
-{
- _mesa_glsl_initialize_variables(instructions, state);
- _mesa_glsl_initialize_constructors(instructions, state);
- _mesa_glsl_initialize_functions(instructions, state);
-
- state->current_function = NULL;
-
- foreach_list_typed (ast_node, ast, link, & state->translation_unit)
- ast->hir(instructions, state);
-}
-
-
-/**
- * If a conversion is available, convert one operand to a different type
- *
- * The \c from \c ir_rvalue is converted "in place".
- *
- * \param to Type that the operand it to be converted to
- * \param from Operand that is being converted
- * \param state GLSL compiler state
- *
- * \return
- * If a conversion is possible (or unnecessary), \c true is returned.
- * Otherwise \c false is returned.
- */
-static bool
-apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- if (to->base_type == from->type->base_type)
- return true;
-
- /* This conversion was added in GLSL 1.20. If the compilation mode is
- * GLSL 1.10, the conversion is skipped.
- */
- if (state->language_version < 120)
- return false;
-
- /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
- *
- * "There are no implicit array or structure conversions. For
- * example, an array of int cannot be implicitly converted to an
- * array of float. There are no implicit conversions between
- * signed and unsigned integers."
- */
- /* FINISHME: The above comment is partially a lie. There is int/uint
- * FINISHME: conversion for immediate constants.
- */
- if (!to->is_float() || !from->type->is_numeric())
- return false;
-
- switch (from->type->base_type) {
- case GLSL_TYPE_INT:
- from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
- break;
- case GLSL_TYPE_UINT:
- from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
- break;
- case GLSL_TYPE_BOOL:
- from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
- break;
- default:
- assert(0);
- }
-
- return true;
-}
-
-
-static const struct glsl_type *
-arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
- bool multiply,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- const glsl_type *type_a = value_a->type;
- const glsl_type *type_b = value_b->type;
-
- /* From GLSL 1.50 spec, page 56:
- *
- * "The arithmetic binary operators add (+), subtract (-),
- * multiply (*), and divide (/) operate on integer and
- * floating-point scalars, vectors, and matrices."
- */
- if (!type_a->is_numeric() || !type_b->is_numeric()) {
- _mesa_glsl_error(loc, state,
- "Operands to arithmetic operators must be numeric");
- return glsl_type::error_type;
- }
-
-
- /* "If one operand is floating-point based and the other is
- * not, then the conversions from Section 4.1.10 "Implicit
- * Conversions" are applied to the non-floating-point-based operand."
- */
- if (!apply_implicit_conversion(type_a, value_b, state)
- && !apply_implicit_conversion(type_b, value_a, state)) {
- _mesa_glsl_error(loc, state,
- "Could not implicitly convert operands to "
- "arithmetic operator");
- return glsl_type::error_type;
- }
- type_a = value_a->type;
- type_b = value_b->type;
-
- /* "If the operands are integer types, they must both be signed or
- * both be unsigned."
- *
- * From this rule and the preceeding conversion it can be inferred that
- * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
- * The is_numeric check above already filtered out the case where either
- * type is not one of these, so now the base types need only be tested for
- * equality.
- */
- if (type_a->base_type != type_b->base_type) {
- _mesa_glsl_error(loc, state,
- "base type mismatch for arithmetic operator");
- return glsl_type::error_type;
- }
-
- /* "All arithmetic binary operators result in the same fundamental type
- * (signed integer, unsigned integer, or floating-point) as the
- * operands they operate on, after operand type conversion. After
- * conversion, the following cases are valid
- *
- * * The two operands are scalars. In this case the operation is
- * applied, resulting in a scalar."
- */
- if (type_a->is_scalar() && type_b->is_scalar())
- return type_a;
-
- /* "* One operand is a scalar, and the other is a vector or matrix.
- * In this case, the scalar operation is applied independently to each
- * component of the vector or matrix, resulting in the same size
- * vector or matrix."
- */
- if (type_a->is_scalar()) {
- if (!type_b->is_scalar())
- return type_b;
- } else if (type_b->is_scalar()) {
- return type_a;
- }
-
- /* All of the combinations of <scalar, scalar>, <vector, scalar>,
- * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
- * handled.
- */
- assert(!type_a->is_scalar());
- assert(!type_b->is_scalar());
-
- /* "* The two operands are vectors of the same size. In this case, the
- * operation is done component-wise resulting in the same size
- * vector."
- */
- if (type_a->is_vector() && type_b->is_vector()) {
- if (type_a == type_b) {
- return type_a;
- } else {
- _mesa_glsl_error(loc, state,
- "vector size mismatch for arithmetic operator");
- return glsl_type::error_type;
- }
- }
-
- /* All of the combinations of <scalar, scalar>, <vector, scalar>,
- * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
- * <vector, vector> have been handled. At least one of the operands must
- * be matrix. Further, since there are no integer matrix types, the base
- * type of both operands must be float.
- */
- assert(type_a->is_matrix() || type_b->is_matrix());
- assert(type_a->base_type == GLSL_TYPE_FLOAT);
- assert(type_b->base_type == GLSL_TYPE_FLOAT);
-
- /* "* The operator is add (+), subtract (-), or divide (/), and the
- * operands are matrices with the same number of rows and the same
- * number of columns. In this case, the operation is done component-
- * wise resulting in the same size matrix."
- * * The operator is multiply (*), where both operands are matrices or
- * one operand is a vector and the other a matrix. A right vector
- * operand is treated as a column vector and a left vector operand as a
- * row vector. In all these cases, it is required that the number of
- * columns of the left operand is equal to the number of rows of the
- * right operand. Then, the multiply (*) operation does a linear
- * algebraic multiply, yielding an object that has the same number of
- * rows as the left operand and the same number of columns as the right
- * operand. Section 5.10 "Vector and Matrix Operations" explains in
- * more detail how vectors and matrices are operated on."
- */
- if (! multiply) {
- if (type_a == type_b)
- return type_a;
- } else {
- if (type_a->is_matrix() && type_b->is_matrix()) {
- /* Matrix multiply. The columns of A must match the rows of B. Given
- * the other previously tested constraints, this means the vector type
- * of a row from A must be the same as the vector type of a column from
- * B.
- */
- if (type_a->row_type() == type_b->column_type()) {
- /* The resulting matrix has the number of columns of matrix B and
- * the number of rows of matrix A. We get the row count of A by
- * looking at the size of a vector that makes up a column. The
- * transpose (size of a row) is done for B.
- */
- const glsl_type *const type =
- glsl_type::get_instance(type_a->base_type,
- type_a->column_type()->vector_elements,
- type_b->row_type()->vector_elements);
- assert(type != glsl_type::error_type);
-
- return type;
- }
- } else if (type_a->is_matrix()) {
- /* A is a matrix and B is a column vector. Columns of A must match
- * rows of B. Given the other previously tested constraints, this
- * means the vector type of a row from A must be the same as the
- * vector the type of B.
- */
- if (type_a->row_type() == type_b)
- return type_b;
- } else {
- assert(type_b->is_matrix());
-
- /* A is a row vector and B is a matrix. Columns of A must match rows
- * of B. Given the other previously tested constraints, this means
- * the type of A must be the same as the vector type of a column from
- * B.
- */
- if (type_a == type_b->column_type())
- return type_a;
- }
-
- _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
- return glsl_type::error_type;
- }
-
-
- /* "All other cases are illegal."
- */
- _mesa_glsl_error(loc, state, "type mismatch");
- return glsl_type::error_type;
-}
-
-
-static const struct glsl_type *
-unary_arithmetic_result_type(const struct glsl_type *type,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- /* From GLSL 1.50 spec, page 57:
- *
- * "The arithmetic unary operators negate (-), post- and pre-increment
- * and decrement (-- and ++) operate on integer or floating-point
- * values (including vectors and matrices). All unary operators work
- * component-wise on their operands. These result with the same type
- * they operated on."
- */
- if (!type->is_numeric()) {
- _mesa_glsl_error(loc, state,
- "Operands to arithmetic operators must be numeric");
- return glsl_type::error_type;
- }
-
- return type;
-}
-
-
-static const struct glsl_type *
-modulus_result_type(const struct glsl_type *type_a,
- const struct glsl_type *type_b,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- /* From GLSL 1.50 spec, page 56:
- * "The operator modulus (%) operates on signed or unsigned integers or
- * integer vectors. The operand types must both be signed or both be
- * unsigned."
- */
- if (!type_a->is_integer() || !type_b->is_integer()
- || (type_a->base_type != type_b->base_type)) {
- _mesa_glsl_error(loc, state, "type mismatch");
- return glsl_type::error_type;
- }
-
- /* "The operands cannot be vectors of differing size. If one operand is
- * a scalar and the other vector, then the scalar is applied component-
- * wise to the vector, resulting in the same type as the vector. If both
- * are vectors of the same size, the result is computed component-wise."
- */
- if (type_a->is_vector()) {
- if (!type_b->is_vector()
- || (type_a->vector_elements == type_b->vector_elements))
- return type_a;
- } else
- return type_b;
-
- /* "The operator modulus (%) is not defined for any other data types
- * (non-integer types)."
- */
- _mesa_glsl_error(loc, state, "type mismatch");
- return glsl_type::error_type;
-}
-
-
-static const struct glsl_type *
-relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- const glsl_type *type_a = value_a->type;
- const glsl_type *type_b = value_b->type;
-
- /* From GLSL 1.50 spec, page 56:
- * "The relational operators greater than (>), less than (<), greater
- * than or equal (>=), and less than or equal (<=) operate only on
- * scalar integer and scalar floating-point expressions."
- */
- if (!type_a->is_numeric()
- || !type_b->is_numeric()
- || !type_a->is_scalar()
- || !type_b->is_scalar()) {
- _mesa_glsl_error(loc, state,
- "Operands to relational operators must be scalar and "
- "numeric");
- return glsl_type::error_type;
- }
-
- /* "Either the operands' types must match, or the conversions from
- * Section 4.1.10 "Implicit Conversions" will be applied to the integer
- * operand, after which the types must match."
- */
- if (!apply_implicit_conversion(type_a, value_b, state)
- && !apply_implicit_conversion(type_b, value_a, state)) {
- _mesa_glsl_error(loc, state,
- "Could not implicitly convert operands to "
- "relational operator");
- return glsl_type::error_type;
- }
- type_a = value_a->type;
- type_b = value_b->type;
-
- if (type_a->base_type != type_b->base_type) {
- _mesa_glsl_error(loc, state, "base type mismatch");
- return glsl_type::error_type;
- }
-
- /* "The result is scalar Boolean."
- */
- return glsl_type::bool_type;
-}
-
-
-/**
- * Validates that a value can be assigned to a location with a specified type
- *
- * Validates that \c rhs can be assigned to some location. If the types are
- * not an exact match but an automatic conversion is possible, \c rhs will be
- * converted.
- *
- * \return
- * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
- * Otherwise the actual RHS to be assigned will be returned. This may be
- * \c rhs, or it may be \c rhs after some type conversion.
- *
- * \note
- * In addition to being used for assignments, this function is used to
- * type-check return values.
- */
-ir_rvalue *
-validate_assignment(struct _mesa_glsl_parse_state *state,
- const glsl_type *lhs_type, ir_rvalue *rhs)
-{
- const glsl_type *rhs_type = rhs->type;
-
- /* If there is already some error in the RHS, just return it. Anything
- * else will lead to an avalanche of error message back to the user.
- */
- if (rhs_type->is_error())
- return rhs;
-
- /* If the types are identical, the assignment can trivially proceed.
- */
- if (rhs_type == lhs_type)
- return rhs;
-
- /* If the array element types are the same and the size of the LHS is zero,
- * the assignment is okay.
- *
- * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
- * is handled by ir_dereference::is_lvalue.
- */
- if (lhs_type->is_array() && rhs->type->is_array()
- && (lhs_type->element_type() == rhs->type->element_type())
- && (lhs_type->array_size() == 0)) {
- return rhs;
- }
-
- /* Check for implicit conversion in GLSL 1.20 */
- if (apply_implicit_conversion(lhs_type, rhs, state)) {
- rhs_type = rhs->type;
- if (rhs_type == lhs_type)
- return rhs;
- }
-
- return NULL;
-}
-
-ir_rvalue *
-do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
- ir_rvalue *lhs, ir_rvalue *rhs,
- YYLTYPE lhs_loc)
-{
- void *ctx = talloc_parent(state);
- bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
-
- if (!error_emitted) {
- /* FINISHME: This does not handle 'foo.bar.a.b.c[5].d = 5' */
- if (!lhs->is_lvalue()) {
- _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
- error_emitted = true;
- }
- }
-
- ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs);
- if (new_rhs == NULL) {
- _mesa_glsl_error(& lhs_loc, state, "type mismatch");
- } else {
- rhs = new_rhs;
-
- /* If the LHS array was not declared with a size, it takes it size from
- * the RHS. If the LHS is an l-value and a whole array, it must be a
- * dereference of a variable. Any other case would require that the LHS
- * is either not an l-value or not a whole array.
- */
- if (lhs->type->array_size() == 0) {
- ir_dereference *const d = lhs->as_dereference();
-
- assert(d != NULL);
-
- ir_variable *const var = d->variable_referenced();
-
- assert(var != NULL);
-
- if (var->max_array_access >= unsigned(rhs->type->array_size())) {
- /* FINISHME: This should actually log the location of the RHS. */
- _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
- "previous access",
- var->max_array_access);
- }
-
- var->type = glsl_type::get_array_instance(state,
- lhs->type->element_type(),
- rhs->type->array_size());
- }
- }
-
- /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
- * but not post_inc) need the converted assigned value as an rvalue
- * to handle things like:
- *
- * i = j += 1;
- *
- * So we always just store the computed value being assigned to a
- * temporary and return a deref of that temporary. If the rvalue
- * ends up not being used, the temp will get copy-propagated out.
- */
- ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp");
- ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
- instructions->push_tail(var);
- instructions->push_tail(new(ctx) ir_assignment(deref_var,
- rhs,
- NULL));
- deref_var = new(ctx) ir_dereference_variable(var);
-
- instructions->push_tail(new(ctx) ir_assignment(lhs,
- deref_var,
- NULL));
-
- return new(ctx) ir_dereference_variable(var);
-}
-
-
-/**
- * Generate a new temporary and add its declaration to the instruction stream
- */
-static ir_variable *
-generate_temporary(const glsl_type *type, exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- char *name = (char *) malloc(sizeof(char) * 13);
-
- snprintf(name, 13, "tmp_%08X", state->temp_index);
- state->temp_index++;
-
- ir_variable *const var = new(ctx) ir_variable(type, name);
- instructions->push_tail(var);
-
- return var;
-}
-
-
-static ir_rvalue *
-get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
-{
- void *ctx = talloc_parent(lvalue);
- ir_variable *var;
-
- /* FINISHME: Give unique names to the temporaries. */
- var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp");
- var->mode = ir_var_auto;
-
- instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
- lvalue, NULL));
-
- /* Once we've created this temporary, mark it read only so it's no
- * longer considered an lvalue.
- */
- var->read_only = true;
-
- return new(ctx) ir_dereference_variable(var);
-}
-
-
-ir_rvalue *
-ast_node::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- (void) instructions;
- (void) state;
-
- return NULL;
-}
-
-
-ir_rvalue *
-ast_expression::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- static const int operations[AST_NUM_OPERATORS] = {
- -1, /* ast_assign doesn't convert to ir_expression. */
- -1, /* ast_plus doesn't convert to ir_expression. */
- ir_unop_neg,
- ir_binop_add,
- ir_binop_sub,
- ir_binop_mul,
- ir_binop_div,
- ir_binop_mod,
- ir_binop_lshift,
- ir_binop_rshift,
- ir_binop_less,
- ir_binop_greater,
- ir_binop_lequal,
- ir_binop_gequal,
- ir_binop_equal,
- ir_binop_nequal,
- ir_binop_bit_and,
- ir_binop_bit_xor,
- ir_binop_bit_or,
- ir_unop_bit_not,
- ir_binop_logic_and,
- ir_binop_logic_xor,
- ir_binop_logic_or,
- ir_unop_logic_not,
-
- /* Note: The following block of expression types actually convert
- * to multiple IR instructions.
- */
- ir_binop_mul, /* ast_mul_assign */
- ir_binop_div, /* ast_div_assign */
- ir_binop_mod, /* ast_mod_assign */
- ir_binop_add, /* ast_add_assign */
- ir_binop_sub, /* ast_sub_assign */
- ir_binop_lshift, /* ast_ls_assign */
- ir_binop_rshift, /* ast_rs_assign */
- ir_binop_bit_and, /* ast_and_assign */
- ir_binop_bit_xor, /* ast_xor_assign */
- ir_binop_bit_or, /* ast_or_assign */
-
- -1, /* ast_conditional doesn't convert to ir_expression. */
- ir_binop_add, /* ast_pre_inc. */
- ir_binop_sub, /* ast_pre_dec. */
- ir_binop_add, /* ast_post_inc. */
- ir_binop_sub, /* ast_post_dec. */
- -1, /* ast_field_selection doesn't conv to ir_expression. */
- -1, /* ast_array_index doesn't convert to ir_expression. */
- -1, /* ast_function_call doesn't conv to ir_expression. */
- -1, /* ast_identifier doesn't convert to ir_expression. */
- -1, /* ast_int_constant doesn't convert to ir_expression. */
- -1, /* ast_uint_constant doesn't conv to ir_expression. */
- -1, /* ast_float_constant doesn't conv to ir_expression. */
- -1, /* ast_bool_constant doesn't conv to ir_expression. */
- -1, /* ast_sequence doesn't convert to ir_expression. */
- };
- ir_rvalue *result = NULL;
- ir_rvalue *op[2];
- const struct glsl_type *type = glsl_type::error_type;
- bool error_emitted = false;
- YYLTYPE loc;
-
- loc = this->get_location();
-
- switch (this->oper) {
- case ast_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- result = do_assignment(instructions, state, op[0], op[1],
- this->subexpressions[0]->get_location());
- error_emitted = result->type->is_error();
- type = result->type;
- break;
- }
-
- case ast_plus:
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- error_emitted = op[0]->type->is_error();
- if (type->is_error())
- op[0]->type = type;
-
- result = op[0];
- break;
-
- case ast_neg:
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- type = unary_arithmetic_result_type(op[0]->type, state, & loc);
-
- error_emitted = type->is_error();
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], NULL);
- break;
-
- case ast_add:
- case ast_sub:
- case ast_mul:
- case ast_div:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = arithmetic_result_type(op[0], op[1],
- (this->oper == ast_mul),
- state, & loc);
- error_emitted = type->is_error();
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- break;
-
- case ast_mod:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
-
- assert(operations[this->oper] == ir_binop_mod);
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- error_emitted = type->is_error();
- break;
-
- case ast_lshift:
- case ast_rshift:
- _mesa_glsl_error(& loc, state, "FINISHME: implement bit-shift operators");
- error_emitted = true;
- break;
-
- case ast_less:
- case ast_greater:
- case ast_lequal:
- case ast_gequal:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = relational_result_type(op[0], op[1], state, & loc);
-
- /* The relational operators must either generate an error or result
- * in a scalar boolean. See page 57 of the GLSL 1.50 spec.
- */
- assert(type->is_error()
- || ((type->base_type == GLSL_TYPE_BOOL)
- && type->is_scalar()));
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- error_emitted = type->is_error();
- break;
-
- case ast_nequal:
- case ast_equal:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
- *
- * "The equality operators equal (==), and not equal (!=)
- * operate on all types. They result in a scalar Boolean. If
- * the operand types do not match, then there must be a
- * conversion from Section 4.1.10 "Implicit Conversions"
- * applied to one operand that can make them match, in which
- * case this conversion is done."
- */
- if ((!apply_implicit_conversion(op[0]->type, op[1], state)
- && !apply_implicit_conversion(op[1]->type, op[0], state))
- || (op[0]->type != op[1]->type)) {
- _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
- "type", (this->oper == ast_equal) ? "==" : "!=");
- error_emitted = true;
- } else if ((state->language_version <= 110)
- && (op[0]->type->is_array() || op[1]->type->is_array())) {
- _mesa_glsl_error(& loc, state, "array comparisons forbidden in "
- "GLSL 1.10");
- error_emitted = true;
- }
-
- result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], op[1]);
- type = glsl_type::bool_type;
-
- assert(result->type == glsl_type::bool_type);
- break;
-
- case ast_bit_and:
- case ast_bit_xor:
- case ast_bit_or:
- case ast_bit_not:
- _mesa_glsl_error(& loc, state, "FINISHME: implement bit-wise operators");
- error_emitted = true;
- break;
-
- case ast_logic_and: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_constant *op0_const = op[0]->constant_expression_value();
- if (op0_const) {
- if (op0_const->value.b[0]) {
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
- result = op[1];
- } else {
- result = op0_const;
- }
- type = glsl_type::bool_type;
- } else {
- ir_if *const stmt = new(ctx) ir_if(op[0]);
- instructions->push_tail(stmt);
-
- op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
- instructions, state);
-
- ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const then_assign =
- new(ctx) ir_assignment(then_deref, op[1], NULL);
- stmt->then_instructions.push_tail(then_assign);
-
- ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const else_assign =
- new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL);
- stmt->else_instructions.push_tail(else_assign);
-
- result = new(ctx) ir_dereference_variable(tmp);
- type = tmp->type;
- }
- break;
- }
-
- case ast_logic_or: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_constant *op0_const = op[0]->constant_expression_value();
- if (op0_const) {
- if (op0_const->value.b[0]) {
- result = op0_const;
- } else {
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
- result = op[1];
- }
- type = glsl_type::bool_type;
- } else {
- ir_if *const stmt = new(ctx) ir_if(op[0]);
- instructions->push_tail(stmt);
-
- ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
- instructions, state);
-
- op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state, "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const then_assign =
- new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL);
- stmt->then_instructions.push_tail(then_assign);
-
- ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const else_assign =
- new(ctx) ir_assignment(else_deref, op[1], NULL);
- stmt->else_instructions.push_tail(else_assign);
-
- result = new(ctx) ir_dereference_variable(tmp);
- type = tmp->type;
- }
- break;
- }
-
- case ast_logic_xor:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
-
- result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], op[1]);
- type = glsl_type::bool_type;
- break;
-
- case ast_logic_not:
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "operand of `!' must be scalar boolean");
- error_emitted = true;
- }
-
- result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], NULL);
- type = glsl_type::bool_type;
- break;
-
- case ast_mul_assign:
- case ast_div_assign:
- case ast_add_assign:
- case ast_sub_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = arithmetic_result_type(op[0], op[1],
- (this->oper == ast_mul_assign),
- state, & loc);
-
- ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- result = do_assignment(instructions, state,
- (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
- this->subexpressions[0]->get_location());
- type = result->type;
- error_emitted = (op[0]->type->is_error());
-
- /* GLSL 1.10 does not allow array assignment. However, we don't have to
- * explicitly test for this because none of the binary expression
- * operators allow array operands either.
- */
-
- break;
- }
-
- case ast_mod_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
-
- assert(operations[this->oper] == ir_binop_mod);
-
- struct ir_rvalue *temp_rhs;
- temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- result = do_assignment(instructions, state,
- (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
- this->subexpressions[0]->get_location());
- type = result->type;
- error_emitted = type->is_error();
- break;
- }
-
- case ast_ls_assign:
- case ast_rs_assign:
- _mesa_glsl_error(& loc, state,
- "FINISHME: implement bit-shift assignment operators");
- error_emitted = true;
- break;
-
- case ast_and_assign:
- case ast_xor_assign:
- case ast_or_assign:
- _mesa_glsl_error(& loc, state,
- "FINISHME: implement logic assignment operators");
- error_emitted = true;
- break;
-
- case ast_conditional: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
- *
- * "The ternary selection operator (?:). It operates on three
- * expressions (exp1 ? exp2 : exp3). This operator evaluates the
- * first expression, which must result in a scalar Boolean."
- */
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state, "?: condition must be scalar boolean");
- error_emitted = true;
- }
-
- /* The :? operator is implemented by generating an anonymous temporary
- * followed by an if-statement. The last instruction in each branch of
- * the if-statement assigns a value to the anonymous temporary. This
- * temporary is the r-value of the expression.
- */
- exec_list then_instructions;
- exec_list else_instructions;
-
- op[1] = this->subexpressions[1]->hir(&then_instructions, state);
- op[2] = this->subexpressions[2]->hir(&else_instructions, state);
-
- /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
- *
- * "The second and third expressions can be any type, as
- * long their types match, or there is a conversion in
- * Section 4.1.10 "Implicit Conversions" that can be applied
- * to one of the expressions to make their types match. This
- * resulting matching type is the type of the entire
- * expression."
- */
- if ((!apply_implicit_conversion(op[1]->type, op[2], state)
- && !apply_implicit_conversion(op[2]->type, op[1], state))
- || (op[1]->type != op[2]->type)) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
- "operator must have matching types.");
- error_emitted = true;
- type = glsl_type::error_type;
- } else {
- type = op[1]->type;
- }
-
- ir_constant *cond_val = op[0]->constant_expression_value();
- ir_constant *then_val = op[1]->constant_expression_value();
- ir_constant *else_val = op[2]->constant_expression_value();
-
- if (then_instructions.is_empty()
- && else_instructions.is_empty()
- && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
- result = (cond_val->value.b[0]) ? then_val : else_val;
- } else {
- ir_variable *const tmp = generate_temporary(type,
- instructions, state);
-
- ir_if *const stmt = new(ctx) ir_if(op[0]);
- instructions->push_tail(stmt);
-
- then_instructions.move_nodes_to(& stmt->then_instructions);
- ir_dereference *const then_deref =
- new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const then_assign =
- new(ctx) ir_assignment(then_deref, op[1], NULL);
- stmt->then_instructions.push_tail(then_assign);
-
- else_instructions.move_nodes_to(& stmt->else_instructions);
- ir_dereference *const else_deref =
- new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const else_assign =
- new(ctx) ir_assignment(else_deref, op[2], NULL);
- stmt->else_instructions.push_tail(else_assign);
-
- result = new(ctx) ir_dereference_variable(tmp);
- }
- break;
- }
-
- case ast_pre_inc:
- case ast_pre_dec: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
-
- type = arithmetic_result_type(op[0], op[1], false, state, & loc);
-
- struct ir_rvalue *temp_rhs;
- temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- result = do_assignment(instructions, state,
- (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
- this->subexpressions[0]->get_location());
- type = result->type;
- error_emitted = op[0]->type->is_error();
- break;
- }
-
- case ast_post_inc:
- case ast_post_dec: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
-
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
-
- type = arithmetic_result_type(op[0], op[1], false, state, & loc);
-
- struct ir_rvalue *temp_rhs;
- temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- /* Get a temporary of a copy of the lvalue before it's modified.
- * This may get thrown away later.
- */
- result = get_lvalue_copy(instructions, (ir_rvalue *)op[0]->clone(NULL));
-
- (void)do_assignment(instructions, state,
- (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
- this->subexpressions[0]->get_location());
-
- type = result->type;
- error_emitted = op[0]->type->is_error();
- break;
- }
-
- case ast_field_selection:
- result = _mesa_ast_field_selection_to_hir(this, instructions, state);
- type = result->type;
- break;
-
- case ast_array_index: {
- YYLTYPE index_loc = subexpressions[1]->get_location();
-
- op[0] = subexpressions[0]->hir(instructions, state);
- op[1] = subexpressions[1]->hir(instructions, state);
-
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
-
- ir_rvalue *const array = op[0];
-
- result = new(ctx) ir_dereference_array(op[0], op[1]);
-
- /* Do not use op[0] after this point. Use array.
- */
- op[0] = NULL;
-
-
- if (error_emitted)
- break;
-
- if (!array->type->is_array()
- && !array->type->is_matrix()
- && !array->type->is_vector()) {
- _mesa_glsl_error(& index_loc, state,
- "cannot dereference non-array / non-matrix / "
- "non-vector");
- error_emitted = true;
- }
-
- if (!op[1]->type->is_integer()) {
- _mesa_glsl_error(& index_loc, state,
- "array index must be integer type");
- error_emitted = true;
- } else if (!op[1]->type->is_scalar()) {
- _mesa_glsl_error(& index_loc, state,
- "array index must be scalar");
- error_emitted = true;
- }
-
- /* If the array index is a constant expression and the array has a
- * declared size, ensure that the access is in-bounds. If the array
- * index is not a constant expression, ensure that the array has a
- * declared size.
- */
- ir_constant *const const_index = op[1]->constant_expression_value();
- if (const_index != NULL) {
- const int idx = const_index->value.i[0];
- const char *type_name;
- unsigned bound = 0;
-
- if (array->type->is_matrix()) {
- type_name = "matrix";
- } else if (array->type->is_vector()) {
- type_name = "vector";
- } else {
- type_name = "array";
- }
-
- /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
- *
- * "It is illegal to declare an array with a size, and then
- * later (in the same shader) index the same array with an
- * integral constant expression greater than or equal to the
- * declared size. It is also illegal to index an array with a
- * negative constant expression."
- */
- if (array->type->is_matrix()) {
- if (array->type->row_type()->vector_elements <= idx) {
- bound = array->type->row_type()->vector_elements;
- }
- } else if (array->type->is_vector()) {
- if (array->type->vector_elements <= idx) {
- bound = array->type->vector_elements;
- }
- } else {
- if ((array->type->array_size() > 0)
- && (array->type->array_size() <= idx)) {
- bound = array->type->array_size();
- }
- }
-
- if (bound > 0) {
- _mesa_glsl_error(& loc, state, "%s index must be < %u",
- type_name, bound);
- error_emitted = true;
- } else if (idx < 0) {
- _mesa_glsl_error(& loc, state, "%s index must be >= 0",
- type_name);
- error_emitted = true;
- }
-
- if (array->type->is_array()) {
- /* If the array is a variable dereference, it dereferences the
- * whole array, by definition. Use this to get the variable.
- *
- * FINISHME: Should some methods for getting / setting / testing
- * FINISHME: array access limits be added to ir_dereference?
- */
- ir_variable *const v = array->whole_variable_referenced();
- if ((v != NULL) && (unsigned(idx) > v->max_array_access))
- v->max_array_access = idx;
- }
- }
-
- if (error_emitted)
- result->type = glsl_type::error_type;
-
- type = result->type;
- break;
- }
-
- case ast_function_call:
- /* Should *NEVER* get here. ast_function_call should always be handled
- * by ast_function_expression::hir.
- */
- assert(0);
- break;
-
- case ast_identifier: {
- /* ast_identifier can appear several places in a full abstract syntax
- * tree. This particular use must be at location specified in the grammar
- * as 'variable_identifier'.
- */
- ir_variable *var =
- state->symbols->get_variable(this->primary_expression.identifier);
-
- result = new(ctx) ir_dereference_variable(var);
-
- if (var != NULL) {
- type = result->type;
- } else {
- _mesa_glsl_error(& loc, state, "`%s' undeclared",
- this->primary_expression.identifier);
-
- error_emitted = true;
- }
- break;
- }
-
- case ast_int_constant:
- type = glsl_type::int_type;
- result = new(ctx) ir_constant(this->primary_expression.int_constant);
- break;
-
- case ast_uint_constant:
- type = glsl_type::uint_type;
- result = new(ctx) ir_constant(this->primary_expression.uint_constant);
- break;
-
- case ast_float_constant:
- type = glsl_type::float_type;
- result = new(ctx) ir_constant(this->primary_expression.float_constant);
- break;
-
- case ast_bool_constant:
- type = glsl_type::bool_type;
- result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
- break;
-
- case ast_sequence: {
- /* It should not be possible to generate a sequence in the AST without
- * any expressions in it.
- */
- assert(!this->expressions.is_empty());
-
- /* The r-value of a sequence is the last expression in the sequence. If
- * the other expressions in the sequence do not have side-effects (and
- * therefore add instructions to the instruction list), they get dropped
- * on the floor.
- */
- foreach_list_typed (ast_node, ast, link, &this->expressions)
- result = ast->hir(instructions, state);
-
- type = result->type;
-
- /* Any errors should have already been emitted in the loop above.
- */
- error_emitted = true;
- break;
- }
- }
-
- if (type->is_error() && !error_emitted)
- _mesa_glsl_error(& loc, state, "type mismatch");
-
- return result;
-}
-
-
-ir_rvalue *
-ast_expression_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- /* It is possible to have expression statements that don't have an
- * expression. This is the solitary semicolon:
- *
- * for (i = 0; i < 5; i++)
- * ;
- *
- * In this case the expression will be NULL. Test for NULL and don't do
- * anything in that case.
- */
- if (expression != NULL)
- expression->hir(instructions, state);
-
- /* Statements do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_compound_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- if (new_scope)
- state->symbols->push_scope();
-
- foreach_list_typed (ast_node, ast, link, &this->statements)
- ast->hir(instructions, state);
-
- if (new_scope)
- state->symbols->pop_scope();
-
- /* Compound statements do not have r-values.
- */
- return NULL;
-}
-
-
-static const glsl_type *
-process_array_type(const glsl_type *base, ast_node *array_size,
- struct _mesa_glsl_parse_state *state)
-{
- unsigned length = 0;
-
- /* FINISHME: Reject delcarations of multidimensional arrays. */
-
- if (array_size != NULL) {
- exec_list dummy_instructions;
- ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
- YYLTYPE loc = array_size->get_location();
-
- /* FINISHME: Verify that the grammar forbids side-effects in array
- * FINISHME: sizes. i.e., 'vec4 [x = 12] data'
- */
- assert(dummy_instructions.is_empty());
-
- if (ir != NULL) {
- if (!ir->type->is_integer()) {
- _mesa_glsl_error(& loc, state, "array size must be integer type");
- } else if (!ir->type->is_scalar()) {
- _mesa_glsl_error(& loc, state, "array size must be scalar type");
- } else {
- ir_constant *const size = ir->constant_expression_value();
-
- if (size == NULL) {
- _mesa_glsl_error(& loc, state, "array size must be a "
- "constant valued expression");
- } else if (size->value.i[0] <= 0) {
- _mesa_glsl_error(& loc, state, "array size must be > 0");
- } else {
- assert(size->type == ir->type);
- length = size->value.u[0];
- }
- }
- }
- }
-
- return glsl_type::get_array_instance(state, base, length);
-}
-
-
-const glsl_type *
-ast_type_specifier::glsl_type(const char **name,
- struct _mesa_glsl_parse_state *state) const
-{
- const struct glsl_type *type;
-
- if ((this->type_specifier == ast_struct) && (this->type_name == NULL)) {
- /* FINISHME: Handle annonymous structures. */
- type = NULL;
- } else {
- type = state->symbols->get_type(this->type_name);
- *name = this->type_name;
-
- if (this->is_array) {
- type = process_array_type(type, this->array_size, state);
- }
- }
-
- return type;
-}
-
-
-static void
-apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
- struct ir_variable *var,
- struct _mesa_glsl_parse_state *state,
- YYLTYPE *loc)
-{
- if (qual->invariant)
- var->invariant = 1;
-
- /* FINISHME: Mark 'in' variables at global scope as read-only. */
- if (qual->constant || qual->attribute || qual->uniform
- || (qual->varying && (state->target == fragment_shader)))
- var->read_only = 1;
-
- if (qual->centroid)
- var->centroid = 1;
-
- if (qual->attribute && state->target != vertex_shader) {
- var->type = glsl_type::error_type;
- _mesa_glsl_error(loc, state,
- "`attribute' variables may not be declared in the "
- "%s shader",
- _mesa_glsl_shader_target_name(state->target));
- }
-
- /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
- *
- * "The varying qualifier can be used only with the data types
- * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
- * these."
- */
- if (qual->varying) {
- const glsl_type *non_array_type;
-
- if (var->type && var->type->is_array())
- non_array_type = var->type->fields.array;
- else
- non_array_type = var->type;
-
- if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) {
- var->type = glsl_type::error_type;
- _mesa_glsl_error(loc, state,
- "varying variables must be of base type float");
- }
- }
-
- if (qual->in && qual->out)
- var->mode = ir_var_inout;
- else if (qual->attribute || qual->in
- || (qual->varying && (state->target == fragment_shader)))
- var->mode = ir_var_in;
- else if (qual->out || (qual->varying && (state->target == vertex_shader)))
- var->mode = ir_var_out;
- else if (qual->uniform)
- var->mode = ir_var_uniform;
- else
- var->mode = ir_var_auto;
-
- if (qual->uniform)
- var->shader_in = true;
-
- /* Any 'in' or 'inout' variables at global scope must be marked as being
- * shader inputs. Likewise, any 'out' or 'inout' variables at global scope
- * must be marked as being shader outputs.
- */
- if (state->current_function == NULL) {
- switch (var->mode) {
- case ir_var_in:
- case ir_var_uniform:
- var->shader_in = true;
- break;
- case ir_var_out:
- var->shader_out = true;
- break;
- case ir_var_inout:
- var->shader_in = true;
- var->shader_out = true;
- break;
- default:
- break;
- }
- }
-
- if (qual->flat)
- var->interpolation = ir_var_flat;
- else if (qual->noperspective)
- var->interpolation = ir_var_noperspective;
- else
- var->interpolation = ir_var_smooth;
-
- if (var->type->is_array() && (state->language_version >= 120)) {
- var->array_lvalue = true;
- }
-}
-
-
-ir_rvalue *
-ast_declarator_list::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- const struct glsl_type *decl_type;
- const char *type_name = NULL;
- ir_rvalue *result = NULL;
- YYLTYPE loc = this->get_location();
-
- /* The type specifier may contain a structure definition. Process that
- * before any of the variable declarations.
- */
- (void) this->type->specifier->hir(instructions, state);
-
- /* FINISHME: Handle vertex shader "invariant" declarations that do not
- * FINISHME: include a type. These re-declare built-in variables to be
- * FINISHME: invariant.
- */
-
- decl_type = this->type->specifier->glsl_type(& type_name, state);
- if (this->declarations.is_empty()) {
- /* There are only two valid cases where the declaration list can be
- * empty.
- *
- * 1. The declaration is setting the default precision of a built-in
- * type (e.g., 'precision highp vec4;').
- *
- * 2. Adding 'invariant' to an existing vertex shader output.
- */
-
- if (this->type->qualifier.invariant) {
- } else if (decl_type != NULL) {
- } else {
- _mesa_glsl_error(& loc, state, "incomplete declaration");
- }
- }
-
- foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
- const struct glsl_type *var_type;
- struct ir_variable *var;
-
- /* FINISHME: Emit a warning if a variable declaration shadows a
- * FINISHME: declaration at a higher scope.
- */
-
- if ((decl_type == NULL) || decl_type->is_void()) {
- if (type_name != NULL) {
- _mesa_glsl_error(& loc, state,
- "invalid type `%s' in declaration of `%s'",
- type_name, decl->identifier);
- } else {
- _mesa_glsl_error(& loc, state,
- "invalid type in declaration of `%s'",
- decl->identifier);
- }
- continue;
- }
-
- if (decl->is_array) {
- var_type = process_array_type(decl_type, decl->array_size, state);
- } else {
- var_type = decl_type;
- }
-
- var = new(ctx) ir_variable(var_type, decl->identifier);
-
- /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
- *
- * "Global variables can only use the qualifiers const,
- * attribute, uni form, or varying. Only one may be
- * specified.
- *
- * Local variables can only use the qualifier const."
- *
- * This is relaxed in GLSL 1.30.
- */
- if (state->language_version < 120) {
- if (this->type->qualifier.out) {
- _mesa_glsl_error(& loc, state,
- "`out' qualifier in declaration of `%s' "
- "only valid for function parameters in GLSL 1.10.",
- decl->identifier);
- }
- if (this->type->qualifier.in) {
- _mesa_glsl_error(& loc, state,
- "`in' qualifier in declaration of `%s' "
- "only valid for function parameters in GLSL 1.10.",
- decl->identifier);
- }
- /* FINISHME: Test for other invalid qualifiers. */
- }
-
- apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
- & loc);
-
- /* Attempt to add the variable to the symbol table. If this fails, it
- * means the variable has already been declared at this scope. Arrays
- * fudge this rule a little bit.
- *
- * From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
- *
- * "It is legal to declare an array without a size and then
- * later re-declare the same name as an array of the same
- * type and specify a size."
- */
- if (state->symbols->name_declared_this_scope(decl->identifier)) {
- ir_variable *const earlier =
- state->symbols->get_variable(decl->identifier);
-
- if ((earlier != NULL)
- && (earlier->type->array_size() == 0)
- && var->type->is_array()
- && (var->type->element_type() == earlier->type->element_type())) {
- /* FINISHME: This doesn't match the qualifiers on the two
- * FINISHME: declarations. It's not 100% clear whether this is
- * FINISHME: required or not.
- */
-
- if (var->type->array_size() <= (int)earlier->max_array_access) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "array size must be > %u due to "
- "previous access",
- earlier->max_array_access);
- }
-
- earlier->type = var->type;
- delete var;
- var = NULL;
- } else {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "`%s' redeclared",
- decl->identifier);
- }
-
- continue;
- }
-
- /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
- *
- * "Identifiers starting with "gl_" are reserved for use by
- * OpenGL, and may not be declared in a shader as either a
- * variable or a function."
- */
- if (strncmp(decl->identifier, "gl_", 3) == 0) {
- /* FINISHME: This should only trigger if we're not redefining
- * FINISHME: a builtin (to add a qualifier, for example).
- */
- _mesa_glsl_error(& loc, state,
- "identifier `%s' uses reserved `gl_' prefix",
- decl->identifier);
- }
-
- instructions->push_tail(var);
-
- if (state->current_function != NULL) {
- const char *mode = NULL;
- const char *extra = "";
-
- /* There is no need to check for 'inout' here because the parser will
- * only allow that in function parameter lists.
- */
- if (this->type->qualifier.attribute) {
- mode = "attribute";
- } else if (this->type->qualifier.uniform) {
- mode = "uniform";
- } else if (this->type->qualifier.varying) {
- mode = "varying";
- } else if (this->type->qualifier.in) {
- mode = "in";
- extra = " or in function parameter list";
- } else if (this->type->qualifier.out) {
- mode = "out";
- extra = " or in function parameter list";
- }
-
- if (mode) {
- _mesa_glsl_error(& loc, state,
- "%s variable `%s' must be declared at "
- "global scope%s",
- mode, var->name, extra);
- }
- } else if (var->mode == ir_var_in) {
- if (state->target == vertex_shader) {
- bool error_emitted = false;
-
- /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
- *
- * "Vertex shader inputs can only be float, floating-point
- * vectors, matrices, signed and unsigned integers and integer
- * vectors. Vertex shader inputs can also form arrays of these
- * types, but not structures."
- *
- * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
- *
- * "Vertex shader inputs can only be float, floating-point
- * vectors, matrices, signed and unsigned integers and integer
- * vectors. They cannot be arrays or structures."
- *
- * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
- *
- * "The attribute qualifier can be used only with float,
- * floating-point vectors, and matrices. Attribute variables
- * cannot be declared as arrays or structures."
- */
- const glsl_type *check_type = var->type->is_array()
- ? var->type->fields.array : var->type;
-
- switch (check_type->base_type) {
- case GLSL_TYPE_FLOAT:
- break;
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- if (state->language_version > 120)
- break;
- /* FALLTHROUGH */
- default:
- _mesa_glsl_error(& loc, state,
- "vertex shader input / attribute cannot have "
- "type %s`%s'",
- var->type->is_array() ? "array of " : "",
- check_type->name);
- error_emitted = true;
- }
-
- if (!error_emitted && (state->language_version <= 130)
- && var->type->is_array()) {
- _mesa_glsl_error(& loc, state,
- "vertex shader input / attribute cannot have "
- "array type");
- error_emitted = true;
- }
- }
- }
-
- if (decl->initializer != NULL) {
- YYLTYPE initializer_loc = decl->initializer->get_location();
-
- /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
- *
- * "All uniform variables are read-only and are initialized either
- * directly by an application via API commands, or indirectly by
- * OpenGL."
- */
- if ((state->language_version <= 110)
- && (var->mode == ir_var_uniform)) {
- _mesa_glsl_error(& initializer_loc, state,
- "cannot initialize uniforms in GLSL 1.10");
- }
-
- if (var->type->is_sampler()) {
- _mesa_glsl_error(& initializer_loc, state,
- "cannot initialize samplers");
- }
-
- if ((var->mode == ir_var_in) && (state->current_function == NULL)) {
- _mesa_glsl_error(& initializer_loc, state,
- "cannot initialize %s shader input / %s",
- _mesa_glsl_shader_target_name(state->target),
- (state->target == vertex_shader)
- ? "attribute" : "varying");
- }
-
- ir_dereference *const lhs = new(ctx) ir_dereference_variable(var);
- ir_rvalue *rhs = decl->initializer->hir(instructions, state);
-
- /* Calculate the constant value if this is a const or uniform
- * declaration.
- */
- if (this->type->qualifier.constant || this->type->qualifier.uniform) {
- ir_constant *constant_value = rhs->constant_expression_value();
- if (!constant_value) {
- _mesa_glsl_error(& initializer_loc, state,
- "initializer of %s variable `%s' must be a "
- "constant expression",
- (this->type->qualifier.constant)
- ? "const" : "uniform",
- decl->identifier);
- } else {
- rhs = constant_value;
- var->constant_value = constant_value;
- }
- }
-
- if (rhs && !rhs->type->is_error()) {
- bool temp = var->read_only;
- if (this->type->qualifier.constant)
- var->read_only = false;
-
- /* Never emit code to initialize a uniform.
- */
- if (!this->type->qualifier.uniform)
- result = do_assignment(instructions, state, lhs, rhs,
- this->get_location());
- var->read_only = temp;
- }
- }
-
- /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
- *
- * "It is an error to write to a const variable outside of
- * its declaration, so they must be initialized when
- * declared."
- */
- if (this->type->qualifier.constant && decl->initializer == NULL) {
- _mesa_glsl_error(& loc, state,
- "const declaration of `%s' must be initialized");
- }
-
- /* Add the vairable to the symbol table after processing the initializer.
- * This differs from most C-like languages, but it follows the GLSL
- * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50
- * spec:
- *
- * "Within a declaration, the scope of a name starts immediately
- * after the initializer if present or immediately after the name
- * being declared if not."
- */
- const bool added_variable =
- state->symbols->add_variable(decl->identifier, var);
- assert(added_variable);
- }
-
-
- /* Generally, variable declarations do not have r-values. However,
- * one is used for the declaration in
- *
- * while (bool b = some_condition()) {
- * ...
- * }
- *
- * so we return the rvalue from the last seen declaration here.
- */
- return result;
-}
-
-
-ir_rvalue *
-ast_parameter_declarator::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- const struct glsl_type *type;
- const char *name = NULL;
- YYLTYPE loc = this->get_location();
-
- type = this->type->specifier->glsl_type(& name, state);
-
- if (type == NULL) {
- if (name != NULL) {
- _mesa_glsl_error(& loc, state,
- "invalid type `%s' in declaration of `%s'",
- name, this->identifier);
- } else {
- _mesa_glsl_error(& loc, state,
- "invalid type in declaration of `%s'",
- this->identifier);
- }
-
- type = glsl_type::error_type;
- }
-
- /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
- *
- * "Functions that accept no input arguments need not use void in the
- * argument list because prototypes (or definitions) are required and
- * therefore there is no ambiguity when an empty argument list "( )" is
- * declared. The idiom "(void)" as a parameter list is provided for
- * convenience."
- *
- * Placing this check here prevents a void parameter being set up
- * for a function, which avoids tripping up checks for main taking
- * parameters and lookups of an unnamed symbol.
- */
- if (type->is_void()) {
- if (this->identifier != NULL)
- _mesa_glsl_error(& loc, state,
- "named parameter cannot have type `void'");
-
- is_void = true;
- return NULL;
- }
-
- if (formal_parameter && (this->identifier == NULL)) {
- _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
- return NULL;
- }
-
- is_void = false;
- ir_variable *var = new(ctx) ir_variable(type, this->identifier);
-
- /* FINISHME: Handle array declarations. Note that this requires
- * FINISHME: complete handling of constant expressions.
- */
-
- /* Apply any specified qualifiers to the parameter declaration. Note that
- * for function parameters the default mode is 'in'.
- */
- apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);
- if (var->mode == ir_var_auto)
- var->mode = ir_var_in;
-
- instructions->push_tail(var);
-
- /* Parameter declarations do not have r-values.
- */
- return NULL;
-}
-
-
-void
-ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
- bool formal,
- exec_list *ir_parameters,
- _mesa_glsl_parse_state *state)
-{
- ast_parameter_declarator *void_param = NULL;
- unsigned count = 0;
-
- foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
- param->formal_parameter = formal;
- param->hir(ir_parameters, state);
-
- if (param->is_void)
- void_param = param;
-
- count++;
- }
-
- if ((void_param != NULL) && (count > 1)) {
- YYLTYPE loc = void_param->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`void' parameter must be only parameter");
- }
-}
-
-
-ir_rvalue *
-ast_function::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- ir_function *f = NULL;
- ir_function_signature *sig = NULL;
- exec_list hir_parameters;
-
-
- /* Convert the list of function parameters to HIR now so that they can be
- * used below to compare this function's signature with previously seen
- * signatures for functions with the same name.
- */
- ast_parameter_declarator::parameters_to_hir(& this->parameters,
- is_definition,
- & hir_parameters, state);
-
- const char *return_type_name;
- const glsl_type *return_type =
- this->return_type->specifier->glsl_type(& return_type_name, state);
-
- assert(return_type != NULL);
-
- /* Verify that this function's signature either doesn't match a previously
- * seen signature for a function with the same name, or, if a match is found,
- * that the previously seen signature does not have an associated definition.
- */
- const char *const name = identifier;
- f = state->symbols->get_function(name);
- if (f != NULL) {
- ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
- if (sig != NULL) {
- const char *badvar = sig->qualifiers_match(&hir_parameters);
- if (badvar != NULL) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
- "qualifiers don't match prototype", name, badvar);
- }
-
- if (sig->return_type != return_type) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
- "match prototype", name);
- }
-
- if (is_definition && sig->is_defined) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
- sig = NULL;
- }
- }
- } else if (state->symbols->name_declared_this_scope(name)) {
- /* This function name shadows a non-function use of the same name.
- */
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "function name `%s' conflicts with "
- "non-function", name);
- sig = NULL;
- } else {
- f = new(ctx) ir_function(name);
- state->symbols->add_function(f->name, f);
-
- /* Emit the new function header */
- instructions->push_tail(f);
- }
-
- /* Verify the return type of main() */
- if (strcmp(name, "main") == 0) {
- if (! return_type->is_void()) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "main() must return void");
- }
-
- if (!hir_parameters.is_empty()) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "main() must not take any parameters");
- }
- }
-
- /* Finish storing the information about this new function in its signature.
- */
- if (sig == NULL) {
- sig = new(ctx) ir_function_signature(return_type);
- f->add_signature(sig);
- }
-
- sig->replace_parameters(&hir_parameters);
- signature = sig;
-
- /* Function declarations (prototypes) do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_function_definition::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- prototype->is_definition = true;
- prototype->hir(instructions, state);
-
- ir_function_signature *signature = prototype->signature;
-
- assert(state->current_function == NULL);
- state->current_function = signature;
-
- /* Duplicate parameters declared in the prototype as concrete variables.
- * Add these to the symbol table.
- */
- state->symbols->push_scope();
- foreach_iter(exec_list_iterator, iter, signature->parameters) {
- ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();
-
- assert(var != NULL);
-
- /* The only way a parameter would "exist" is if two parameters have
- * the same name.
- */
- if (state->symbols->name_declared_this_scope(var->name)) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
- } else {
- state->symbols->add_variable(var->name, var);
- }
- }
-
- /* Convert the body of the function to HIR. */
- this->body->hir(&signature->body, state);
- signature->is_defined = true;
-
- state->symbols->pop_scope();
-
- assert(state->current_function == signature);
- state->current_function = NULL;
-
- /* Function definitions do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_jump_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
-
- switch (mode) {
- case ast_return: {
- ir_return *inst;
- assert(state->current_function);
-
- if (opt_return_value) {
- if (state->current_function->return_type->base_type ==
- GLSL_TYPE_VOID) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`return` with a value, in function `%s' "
- "returning void",
- state->current_function->function_name());
- }
-
- ir_expression *const ret = (ir_expression *)
- opt_return_value->hir(instructions, state);
- assert(ret != NULL);
-
- /* FINISHME: Make sure the type of the return value matches the return
- * FINISHME: type of the enclosing function.
- */
-
- inst = new(ctx) ir_return(ret);
- } else {
- if (state->current_function->return_type->base_type !=
- GLSL_TYPE_VOID) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`return' with no value, in function %s returning "
- "non-void",
- state->current_function->function_name());
- }
- inst = new(ctx) ir_return;
- }
-
- instructions->push_tail(inst);
- break;
- }
-
- case ast_discard:
- /* FINISHME: discard support */
- if (state->target != fragment_shader) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`discard' may only appear in a fragment shader");
- }
- break;
-
- case ast_break:
- case ast_continue:
- /* FINISHME: Handle switch-statements. They cannot contain 'continue',
- * FINISHME: and they use a different IR instruction for 'break'.
- */
- /* FINISHME: Correctly handle the nesting. If a switch-statement is
- * FINISHME: inside a loop, a 'continue' is valid and will bind to the
- * FINISHME: loop.
- */
- if (state->loop_or_switch_nesting == NULL) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`%s' may only appear in a loop",
- (mode == ast_break) ? "break" : "continue");
- } else {
- ir_loop *const loop = state->loop_or_switch_nesting->as_loop();
-
- if (loop != NULL) {
- ir_loop_jump *const jump =
- new(ctx) ir_loop_jump((mode == ast_break)
- ? ir_loop_jump::jump_break
- : ir_loop_jump::jump_continue);
- instructions->push_tail(jump);
- }
- }
-
- break;
- }
-
- /* Jump instructions do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_selection_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
-
- ir_rvalue *const condition = this->condition->hir(instructions, state);
-
- /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
- *
- * "Any expression whose type evaluates to a Boolean can be used as the
- * conditional expression bool-expression. Vector types are not accepted
- * as the expression to if."
- *
- * The checks are separated so that higher quality diagnostics can be
- * generated for cases where both rules are violated.
- */
- if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
- YYLTYPE loc = this->condition->get_location();
-
- _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
- "boolean");
- }
-
- ir_if *const stmt = new(ctx) ir_if(condition);
-
- if (then_statement != NULL)
- then_statement->hir(& stmt->then_instructions, state);
-
- if (else_statement != NULL)
- else_statement->hir(& stmt->else_instructions, state);
-
- instructions->push_tail(stmt);
-
- /* if-statements do not have r-values.
- */
- return NULL;
-}
-
-
-void
-ast_iteration_statement::condition_to_hir(ir_loop *stmt,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
-
- if (condition != NULL) {
- ir_rvalue *const cond =
- condition->hir(& stmt->body_instructions, state);
-
- if ((cond == NULL)
- || !cond->type->is_boolean() || !cond->type->is_scalar()) {
- YYLTYPE loc = condition->get_location();
-
- _mesa_glsl_error(& loc, state,
- "loop condition must be scalar boolean");
- } else {
- /* As the first code in the loop body, generate a block that looks
- * like 'if (!condition) break;' as the loop termination condition.
- */
- ir_rvalue *const not_cond =
- new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
- NULL);
-
- ir_if *const if_stmt = new(ctx) ir_if(not_cond);
-
- ir_jump *const break_stmt =
- new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
-
- if_stmt->then_instructions.push_tail(break_stmt);
- stmt->body_instructions.push_tail(if_stmt);
- }
- }
-}
-
-
-ir_rvalue *
-ast_iteration_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
-
- /* For-loops and while-loops start a new scope, but do-while loops do not.
- */
- if (mode != ast_do_while)
- state->symbols->push_scope();
-
- if (init_statement != NULL)
- init_statement->hir(instructions, state);
-
- ir_loop *const stmt = new(ctx) ir_loop();
- instructions->push_tail(stmt);
-
- /* Track the current loop and / or switch-statement nesting.
- */
- ir_instruction *const nesting = state->loop_or_switch_nesting;
- state->loop_or_switch_nesting = stmt;
-
- if (mode != ast_do_while)
- condition_to_hir(stmt, state);
-
- if (body != NULL)
- body->hir(& stmt->body_instructions, state);
-
- if (rest_expression != NULL)
- rest_expression->hir(& stmt->body_instructions, state);
-
- if (mode == ast_do_while)
- condition_to_hir(stmt, state);
-
- if (mode != ast_do_while)
- state->symbols->pop_scope();
-
- /* Restore previous nesting before returning.
- */
- state->loop_or_switch_nesting = nesting;
-
- /* Loops do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_type_specifier::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- if (this->structure != NULL)
- return this->structure->hir(instructions, state);
-
- return NULL;
-}
-
-
-ir_rvalue *
-ast_struct_specifier::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- unsigned decl_count = 0;
-
- /* Make an initial pass over the list of structure fields to determine how
- * many there are. Each element in this list is an ast_declarator_list.
- * This means that we actually need to count the number of elements in the
- * 'declarations' list in each of the elements.
- */
- foreach_list_typed (ast_declarator_list, decl_list, link,
- &this->declarations) {
- foreach_list_const (decl_ptr, & decl_list->declarations) {
- decl_count++;
- }
- }
-
-
- /* Allocate storage for the structure fields and process the field
- * declarations. As the declarations are processed, try to also convert
- * the types to HIR. This ensures that structure definitions embedded in
- * other structure definitions are processed.
- */
- glsl_struct_field *const fields = (glsl_struct_field *)
- malloc(sizeof(*fields) * decl_count);
-
- unsigned i = 0;
- foreach_list_typed (ast_declarator_list, decl_list, link,
- &this->declarations) {
- const char *type_name;
-
- decl_list->type->specifier->hir(instructions, state);
-
- const glsl_type *decl_type =
- decl_list->type->specifier->glsl_type(& type_name, state);
-
- foreach_list_typed (ast_declaration, decl, link,
- &decl_list->declarations) {
- const struct glsl_type *const field_type =
- (decl->is_array)
- ? process_array_type(decl_type, decl->array_size, state)
- : decl_type;
-
- fields[i].type = (field_type != NULL)
- ? field_type : glsl_type::error_type;
- fields[i].name = decl->identifier;
- i++;
- }
- }
-
- assert(i == decl_count);
-
- const char *name;
- if (this->name == NULL) {
- static unsigned anon_count = 1;
- char buf[32];
-
- snprintf(buf, sizeof(buf), "#anon_struct_%04x", anon_count);
- anon_count++;
-
- name = strdup(buf);
- } else {
- name = this->name;
- }
-
- glsl_type *t = new(ctx) glsl_type(fields, decl_count, name);
-
- YYLTYPE loc = this->get_location();
- if (!state->symbols->add_type(name, t)) {
- _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
- } else {
- /* This logic is a bit tricky. It is an error to declare a structure at
- * global scope if there is also a function with the same name.
- */
- if ((state->current_function == NULL)
- && (state->symbols->get_function(name) != NULL)) {
- _mesa_glsl_error(& loc, state, "name `%s' previously defined", name);
- } else {
- t->generate_constructor(state->symbols);
- }
-
- const glsl_type **s = (const glsl_type **)
- realloc(state->user_structures,
- sizeof(state->user_structures[0]) *
- (state->num_user_structures + 1));
- if (s != NULL) {
- s[state->num_user_structures] = t;
- state->user_structures = s;
- state->num_user_structures++;
- }
- }
-
- /* Structure type definitions do not have r-values.
- */
- return NULL;
-}
+++ /dev/null
-/*
- * 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"
-#include "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];
-}
+++ /dev/null
-#! /bin/sh
-
-srcdir=`dirname $0`
-test -z "$srcdir" && srcdir=.
-
-ORIGDIR=`pwd`
-cd $srcdir
-
-autoreconf -v --install || exit 1
-cd $ORIGDIR || exit $?
-
-$srcdir/configure --enable-maintainer-mode "$@"
+++ /dev/null
-/* DO NOT MODIFY - automatically generated by generate_builtins.pl */
-/*
- * 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 <stdio.h>
-#include "glsl_parser_extras.h"
-#include "ir_reader.h"
-
-void
-read_builtins(_mesa_glsl_parse_state *st, exec_list *instructions,
- const char **functions, unsigned count)
-{
- if (st->error)
- return;
-
- for (unsigned i = 0; i < count; i++) {
- _mesa_glsl_read_ir(st, instructions, functions[i]);
-
- if (st->error) {
- printf("error reading builtin: %.35s ...\n", functions[i]);
- return;
- }
- }
-}
-
-/* 110 builtins */
-
-static const char *builtins_110_abs = {
- "((function abs\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float abs (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 abs (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 abs (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 abs (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_all = {
- "((function all\n"
- " (signature bool\n"
- " (parameters\n"
- " (declare (in) bvec2 arg0))\n"
- " ((return (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))\n"
- "\n"
- " (signature bool\n"
- " (parameters\n"
- " (declare (in) bvec3 arg0))\n"
- " ((return (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))\n"
- "\n"
- " (signature bool\n"
- " (parameters\n"
- " (declare (in) bvec4 arg0))\n"
- " ((return (expression bool && (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_any = {
- "((function any\n"
- " (signature bool\n"
- " (parameters\n"
- " (declare (in) bvec2 arg0))\n"
- " ((return (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))\n"
- "\n"
- " (signature bool\n"
- " (parameters\n"
- " (declare (in) bvec3 arg0))\n"
- " ((return (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))\n"
- "\n"
- " (signature bool\n"
- " (parameters\n"
- " (declare (in) bvec4 arg0))\n"
- " ((return (expression bool || (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_asin = {
- "((function asin\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (expression float *\n"
- " (expression float -\n"
- " (expression float *\n"
- " (constant float (3.1415926))\n"
- " (constant float (0.5)))\n"
- " (expression float sqrt\n"
- " (expression float -\n"
- " (constant float (1.0))\n"
- " (expression float abs (var_ref x)))))\n"
- " (expression float +\n"
- " (constant float (1.5707288))\n"
- " (expression float *\n"
- " (expression float abs (var_ref x))\n"
- " (expression float +\n"
- " (constant float (-0.2121144))\n"
- " (expression float *\n"
- " (constant float (0.0742610))\n"
- " (expression float abs (var_ref x))))))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (expression vec2 *\n"
- " (expression float -\n"
- " (expression float *\n"
- " (constant float (3.1415926))\n"
- " (constant float (0.5)))\n"
- " (expression vec2 sqrt\n"
- " (expression vec2 -\n"
- " (constant float (1.0))\n"
- " (expression vec2 abs (var_ref x)))))\n"
- " (expression vec2 +\n"
- " (constant float (1.5707288))\n"
- " (expression vec2 *\n"
- " (expression vec2 abs (var_ref x))\n"
- " (expression vec2 +\n"
- " (constant float (-0.2121144))\n"
- " (expression vec2 *\n"
- " (constant float (0.0742610))\n"
- " (expression vec2 abs (var_ref x))))))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (expression vec3 *\n"
- " (expression vec3 -\n"
- " (expression float *\n"
- " (constant float (3.1415926))\n"
- " (constant float (0.5)))\n"
- " (expression vec3 sqrt\n"
- " (expression vec3 -\n"
- " (constant float (1.0))\n"
- " (expression vec3 abs (var_ref x)))))\n"
- " (expression vec3 +\n"
- " (constant float (1.5707288))\n"
- " (expression vec3 *\n"
- " (expression vec3 abs (var_ref x))\n"
- " (expression vec3 +\n"
- " (constant float (-0.2121144))\n"
- " (expression vec3 *\n"
- " (constant float (0.0742610))\n"
- " (expression vec3 abs (var_ref x))))))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (expression vec4 *\n"
- " (expression vec4 -\n"
- " (expression float *\n"
- " (constant float (3.1415926))\n"
- " (constant float (0.5)))\n"
- " (expression vec4 sqrt\n"
- " (expression vec4 -\n"
- " (constant float (1.0))\n"
- " (expression vec4 abs (var_ref x)))))\n"
- " (expression vec4 +\n"
- " (constant float (1.5707288))\n"
- " (expression vec4 *\n"
- " (expression vec4 abs (var_ref x))\n"
- " (expression vec4 +\n"
- " (constant float (-0.2121144))\n"
- " (expression vec4 *\n"
- " (constant float (0.0742610))\n"
- " (expression vec4 abs (var_ref x))))))))))\n"
- ")\n"
- "\n"
- " (function acos\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (expression float - (constant float (1.5707963))\n"
- " (call asin ((var_ref x)))))))\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (expression vec2 - (constant float (1.5707963))\n"
- " (call asin ((var_ref x)))))))\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (expression vec3 - (constant float (1.5707963))\n"
- " (call asin ((var_ref x)))))))\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (expression vec4 - (constant float (1.5707963))\n"
- " (call asin ((var_ref x)))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_atan = {
- "((function atan\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (call asin ((expression float *\n"
- " (var_ref x)\n"
- " (expression float rsq\n"
- " (expression float +\n"
- " (expression float *\n"
- " (var_ref x)\n"
- " (var_ref x))\n"
- " (constant float (1.0))))))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 y_over_x))\n"
- " ((return (call asin ((expression vec2 *\n"
- " (var_ref y_over_x)\n"
- " (expression vec2 rsq\n"
- " (expression vec2 +\n"
- " (expression vec2 *\n"
- " (var_ref y_over_x)\n"
- " (var_ref y_over_x))\n"
- " (constant float (1.0))))))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 y_over_x))\n"
- " ((return (call asin ((expression vec3 *\n"
- " (var_ref y_over_x)\n"
- " (expression vec3 rsq\n"
- " (expression vec3 +\n"
- " (expression vec3 *\n"
- " (var_ref y_over_x)\n"
- " (var_ref y_over_x))\n"
- " (constant float (1.0))))))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 y_over_x))\n"
- " ((return (call asin ((expression vec4 *\n"
- " (var_ref y_over_x)\n"
- " (expression vec4 rsq\n"
- " (expression vec4 +\n"
- " (expression vec4 *\n"
- " (var_ref y_over_x)\n"
- " (var_ref y_over_x))\n"
- " (constant float (1.0))))))))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float y)\n"
- " (declare (in) float x))\n"
- " ((declare () float r)\n"
- " (if (expression bool >\n"
- " (expression float abs (var_ref x))\n"
- " (constant float (.0001)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r) (call atan ((expression float /\n"
- " (var_ref y)\n"
- " (var_ref x)))))\n"
- " (if (expression bool <\n"
- " (var_ref x)\n"
- " (constant float (0.0)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r)\n"
- " (expression float +\n"
- " (var_ref r)\n"
- " (expression float *\n"
- " (expression int sign (var_ref y))\n"
- " (constant float (3.1415926))))))\n"
- " ()))\n"
- " ())\n"
- " (return (var_ref r))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 y)\n"
- " (declare (in) vec2 x))\n"
- " ((declare () vec2 r)\n"
- " (if (expression bool >\n"
- " (expression vec2 abs (var_ref x))\n"
- " (constant float (.0001)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r) (call atan ((expression vec2 /\n"
- " (var_ref y)\n"
- " (var_ref x)))))\n"
- " (if (expression bool <\n"
- " (var_ref x)\n"
- " (constant float (0.0)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r)\n"
- " (expression vec2 +\n"
- " (var_ref r)\n"
- " (expression vec2 *\n"
- " (expression int sign (var_ref y))\n"
- " (constant float (3.1415926))))))\n"
- " ()))\n"
- " ())\n"
- " (return (var_ref r))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 y)\n"
- " (declare (in) vec3 x))\n"
- " ((declare () vec3 r)\n"
- " (if (expression bool >\n"
- " (expression vec3 abs (var_ref x))\n"
- " (constant float (.0001)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r) (call atan ((expression vec3 /\n"
- " (var_ref y)\n"
- " (var_ref x)))))\n"
- " (if (expression bool <\n"
- " (var_ref x)\n"
- " (constant float (0.0)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r)\n"
- " (expression vec3 +\n"
- " (var_ref r)\n"
- " (expression vec3 *\n"
- " (expression int sign (var_ref y))\n"
- " (constant float (3.1415926))))))\n"
- " ()))\n"
- " ())\n"
- " (return (var_ref r))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 y)\n"
- " (declare (in) vec4 x))\n"
- " ((declare () vec4 r)\n"
- " (if (expression bool >\n"
- " (expression vec4 abs (var_ref x))\n"
- " (constant float (.0001)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r) (call atan ((expression vec4 /\n"
- " (var_ref y)\n"
- " (var_ref x)))))\n"
- " (if (expression bool <\n"
- " (var_ref x)\n"
- " (constant float (0.0)))\n"
- " ((assign (constant bool (1))\n"
- " (var_ref r)\n"
- " (expression vec4 +\n"
- " (var_ref r)\n"
- " (expression vec4 *\n"
- " (expression int sign (var_ref y))\n"
- " (constant float (3.1415926))))))\n"
- " ()))\n"
- " ())\n"
- " (return (var_ref r))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_110_ceil = {
- "((function ceil\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float ceil (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 ceil (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 ceil (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 ceil (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_clamp = {
- "((function clamp\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0)\n"
- " (declare (in) float arg1)\n"
- " (declare (in) float arg2))\n"
- " ((return (expression float max (expression float min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1)\n"
- " (declare (in) vec2 arg2))\n"
- " ((return (expression vec2 max (expression vec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1)\n"
- " (declare (in) vec3 arg2))\n"
- " ((return (expression vec3 max (expression vec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1)\n"
- " (declare (in) vec4 arg2))\n"
- " ((return (expression vec4 max (expression vec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) float arg1)\n"
- " (declare (in) float arg2))\n"
- " ((declare () vec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) float arg1)\n"
- " (declare (in) float arg2))\n"
- " ((declare () vec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) float arg1)\n"
- " (declare (in) float arg2))\n"
- " ((declare () vec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result)) (expression vec4 max (expression vec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "))\n"
-};
-
-static const char *builtins_110_cos = {
- "((function cos\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float angle))\n"
- " ((return (expression float cos (var_ref angle)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 angle))\n"
- " ((return (expression vec2 cos (var_ref angle)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 angle))\n"
- " ((return (expression vec3 cos (var_ref angle)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 angle))\n"
- " ((return (expression vec4 cos (var_ref angle)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_cross = {
- "((function cross\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((declare () vec3 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t))\n"
- " (expression float - (expression float * (swiz y (var_ref arg0)) (swiz z (var_ref arg1)))\n"
- " (expression float * (swiz y (var_ref arg1)) (swiz z (var_ref arg0)))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t))\n"
- " (expression float - (expression float * (swiz z (var_ref arg0)) (swiz x (var_ref arg1)))\n"
- " (expression float * (swiz z (var_ref arg1)) (swiz x (var_ref arg0)))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t))\n"
- " (expression float - (expression float * (swiz x (var_ref arg0)) (swiz y (var_ref arg1)))\n"
- " (expression float * (swiz x (var_ref arg1)) (swiz y (var_ref arg0)))))\n"
- " (return (var_ref t))))\n"
- "))\n"
-};
-
-static const char *builtins_110_degrees = {
- "((function degrees\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float * (var_ref arg0) (constant float (57.295780))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 * (var_ref arg0) (constant float (57.295780))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 * (var_ref arg0) (constant float (57.295780))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 * (var_ref arg0) (constant float (57.295780))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_distance = {
- "((function distance\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float p0)\n"
- " (declare (in) float p1))\n"
- " ((declare () float p)\n"
- " (assign (constant bool (1)) (var_ref p) (expression float - (var_ref p0) (var_ref p1)))\n"
- " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec2 p0)\n"
- " (declare (in) vec2 p1))\n"
- " ((declare () vec2 p)\n"
- " (assign (constant bool (1)) (var_ref p) (expression vec2 - (var_ref p0) (var_ref p1)))\n"
- " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec3 p0)\n"
- " (declare (in) vec3 p1))\n"
- " ((declare () vec3 p)\n"
- " (assign (constant bool (1)) (var_ref p) (expression vec3 - (var_ref p0) (var_ref p1)))\n"
- " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec4 p0)\n"
- " (declare (in) vec4 p1))\n"
- " ((declare () vec4 p)\n"
- " (assign (constant bool (1)) (var_ref p) (expression vec4 - (var_ref p0) (var_ref p1)))\n"
- " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_dot = {
- "((function dot\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0)\n"
- " (declare (in) float arg1))\n"
- " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_equal = {
- "((function equal\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_110_exp = {
- "((function exp\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float exp (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 exp (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 exp (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 exp (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_exp2 = {
- "((function exp2\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float exp2 (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 exp2 (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 exp2 (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 exp2 (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_faceforward = {
- "((function faceforward\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float N)\n"
- " (declare (in) float I)\n"
- " (declare (in) float Nref))\n"
- " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
- " ((return (var_ref N)))\n"
- " ((return (expression float neg (var_ref N)))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 N)\n"
- " (declare (in) vec2 I)\n"
- " (declare (in) vec2 Nref))\n"
- " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
- " ((return (var_ref N)))\n"
- " ((return (expression vec2 neg (var_ref N)))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 N)\n"
- " (declare (in) vec3 I)\n"
- " (declare (in) vec3 Nref))\n"
- " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
- " ((return (var_ref N)))\n"
- " ((return (expression vec3 neg (var_ref N)))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 N)\n"
- " (declare (in) vec4 I)\n"
- " (declare (in) vec4 Nref))\n"
- " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
- " ((return (var_ref N)))\n"
- " ((return (expression vec4 neg (var_ref N)))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_floor = {
- "((function floor\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float floor (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 floor (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 floor (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 floor (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_fract = {
- "((function fract\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (expression float - (var_ref x) (expression float floor (var_ref x))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((declare () vec2 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((declare () vec3 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((declare () vec4 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))\n"
- " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float - (swiz w (var_ref x)) (expression float floor (swiz w (var_ref x)))))\n"
- " (return (var_ref t))))\n"
- "))\n"
- "\n"
-};
-
-static const char *builtins_110_greaterThan = {
- "((function greaterThan\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_110_greaterThanEqual = {
- "((function greaterThanEqual\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_110_inversesqrt = {
- "((function inversesqrt\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float rsq (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 rsq (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 rsq (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 rsq (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_length = {
- "((function length\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
- "\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_lessThan = {
- "((function lessThan\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_110_lessThanEqual = {
- "((function lessThanEqual\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_110_log = {
- "((function log\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float log (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 log (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 log (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 log (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_log2 = {
- "((function log2\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float log2 (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 log2 (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 log2 (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 log2 (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_matrixCompMult = {
- "((function matrixCompMult\n"
- " (signature mat2\n"
- " (parameters\n"
- " (declare (in) mat2 x)\n"
- " (declare (in) mat2 y))\n"
- " ((declare () mat2 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- "(return (var_ref z))))\n"
- "\n"
- " (signature mat3\n"
- " (parameters\n"
- " (declare (in) mat3 x)\n"
- " (declare (in) mat3 y))\n"
- " ((declare () mat3 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
- "(return (var_ref z))))\n"
- "\n"
- " (signature mat4\n"
- " (parameters\n"
- " (declare (in) mat4 x)\n"
- " (declare (in) mat4 y))\n"
- " ((declare () mat4 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec4 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3))))) \n"
- "(return (var_ref z))))\n"
- "))\n"
- "\n"
-};
-
-static const char *builtins_110_max = {
- "((function max\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0)\n"
- " (declare (in) float arg1))\n"
- " ((return (expression float max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((return (expression vec2 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((return (expression vec3 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((return (expression vec4 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result))\n"
- " (expression float max (swiz w (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "))\n"
-};
-
-static const char *builtins_110_min = {
- "((function min\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0)\n"
- " (declare (in) float arg1))\n"
- " ((return (expression float min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((return (expression vec2 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((return (expression vec3 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((return (expression vec4 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result))\n"
- " (expression float min (swiz w (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "))\n"
-};
-
-static const char *builtins_110_mix = {
- "((function mix\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0)\n"
- " (declare (in) float arg1)\n"
- " (declare (in) float arg2))\n"
- " ((return (expression float + (expression float * (var_ref arg0) (expression float - (constant float (1.000000)) (var_ref arg2))) (expression float * (var_ref arg1) (var_ref arg2))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1)\n"
- " (declare (in) vec2 arg2))\n"
- " ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1)\n"
- " (declare (in) vec3 arg2))\n"
- " ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1)\n"
- " (declare (in) vec4 arg2))\n"
- " ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1)\n"
- " (declare (in) float arg2))\n"
- " ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1)\n"
- " (declare (in) float arg2))\n"
- " ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1)\n"
- " (declare (in) float arg2))\n"
- " ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_mod = {
- "((function mod\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0)\n"
- " (declare (in) float arg1))\n"
- " ((return (expression float % (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((return (expression vec2 % (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((return (expression vec3 % (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((return (expression vec4 % (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) float arg1))\n"
- " ((declare () vec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result))\n"
- " (expression float % (swiz w (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "))\n"
-};
-
-static const char *builtins_110_noise_fake = {
- "((function noise1\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (constant float (0)))))\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (constant float (0)))))\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (constant float (0)))))\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (constant float (0)))))\n"
- " )\n"
- "\n"
- " (function noise2\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (constant vec2 (0 0)))))\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (constant vec2 (0 0)))))\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (constant vec2 (0 0)))))\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (constant vec2 (0 0)))))\n"
- " )\n"
- "\n"
- " (function noise3\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (constant vec3 (0 0 0)))))\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (constant vec3 (0 0 0)))))\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (constant vec3 (0 0 0)))))\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (constant vec3 (0 0 0)))))\n"
- " )\n"
- "\n"
- " (function noise4\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (constant vec4 (0 0 0 0)))))\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (constant vec4 (0 0 0 0)))))\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (constant vec4 (0 0 0 0)))))\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (constant vec4 (0 0 0 0)))))\n"
- " )\n"
- ")\n"
-};
-
-static const char *builtins_110_normalize = {
- "((function normalize\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_not = {
- "((function not\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) bvec2 arg0))\n"
- " ((return (expression bvec2 ! (var_ref arg0)))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) bvec3 arg0))\n"
- " ((return (expression bvec3 ! (var_ref arg0)))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) bvec4 arg0))\n"
- " ((return (expression bvec4 ! (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_notEqual = {
- "((function notEqual\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression float != (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression int != (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_110_pow = {
- "((function pow\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0)\n"
- " (declare (in) float arg1))\n"
- " ((return (expression float pow (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0)\n"
- " (declare (in) vec2 arg1))\n"
- " ((return (expression vec2 pow (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0)\n"
- " (declare (in) vec3 arg1))\n"
- " ((return (expression vec3 pow (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0)\n"
- " (declare (in) vec4 arg1))\n"
- " ((return (expression vec4 pow (var_ref arg0) (var_ref arg1)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_radians = {
- "((function radians\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float * (var_ref arg0) (constant float (0.017453))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 * (var_ref arg0) (constant float (0.017453))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 * (var_ref arg0) (constant float (0.017453))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 * (var_ref arg0) (constant float (0.017453))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_reflect = {
- "((function reflect\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float i)\n"
- " (declare (in) float n))\n"
- " ((return (expression float -\n"
- " (var_ref i)\n"
- " (expression float *\n"
- " (constant float (2.0))\n"
- " (expression float *\n"
- " (expression float dot\n"
- " (var_ref n)\n"
- " (var_ref i))\n"
- " (var_ref n)))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 i)\n"
- " (declare (in) vec2 n))\n"
- " ((return (expression vec2 -\n"
- " (var_ref i)\n"
- " (expression vec2 *\n"
- " (constant float (2.0))\n"
- " (expression vec2 *\n"
- " (expression float dot\n"
- " (var_ref n)\n"
- " (var_ref i))\n"
- " (var_ref n)))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 i)\n"
- " (declare (in) vec3 n))\n"
- " ((return (expression vec3 -\n"
- " (var_ref i)\n"
- " (expression vec3 *\n"
- " (constant float (2.0))\n"
- " (expression vec3 *\n"
- " (expression float dot\n"
- " (var_ref n)\n"
- " (var_ref i))\n"
- " (var_ref n)))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 i)\n"
- " (declare (in) vec4 n))\n"
- " ((return (expression vec4 -\n"
- " (var_ref i)\n"
- " (expression vec4 *\n"
- " (constant float (2.0))\n"
- " (expression vec4 *\n"
- " (expression float dot\n"
- " (var_ref n)\n"
- " (var_ref i))\n"
- " (var_ref n)))))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_110_refract = {
- "((function refract\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float i)\n"
- " (declare (in) float n)\n"
- " (declare (in) float eta))\n"
- " ((declare () float k)\n"
- " (assign (constant bool (1)) (var_ref k)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * (var_ref eta)\n"
- " (expression float * (var_ref eta)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * \n"
- " (expression float dot (var_ref n) (var_ref i))\n"
- " (expression float dot (var_ref n) (var_ref i))))))))\n"
- " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
- " ((return (constant float (0.0))))\n"
- " ((return (expression float -\n"
- " (expression float * (var_ref eta) (var_ref i))\n"
- " (expression float *\n"
- " (expression float +\n"
- " (expression float * (var_ref eta)\n"
- " (expression float dot (var_ref n) (var_ref i)))\n"
- " (expression float sqrt (var_ref k)))\n"
- " (var_ref n))))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 i)\n"
- " (declare (in) vec2 n)\n"
- " (declare (in) float eta))\n"
- " ((declare () float k)\n"
- " (assign (constant bool (1)) (var_ref k)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * (var_ref eta)\n"
- " (expression float * (var_ref eta)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * \n"
- " (expression float dot (var_ref n) (var_ref i))\n"
- " (expression float dot (var_ref n) (var_ref i))))))))\n"
- " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
- " ((return (constant vec2 (0.0 0.0))))\n"
- " ((return (expression vec2 -\n"
- " (expression vec2 * (var_ref eta) (var_ref i))\n"
- " (expression vec2 *\n"
- " (expression float +\n"
- " (expression float * (var_ref eta)\n"
- " (expression float dot (var_ref n) (var_ref i)))\n"
- " (expression float sqrt (var_ref k)))\n"
- " (var_ref n))))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 i)\n"
- " (declare (in) vec3 n)\n"
- " (declare (in) float eta))\n"
- " ((declare () float k)\n"
- " (assign (constant bool (1)) (var_ref k)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * (var_ref eta)\n"
- " (expression float * (var_ref eta)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * \n"
- " (expression float dot (var_ref n) (var_ref i))\n"
- " (expression float dot (var_ref n) (var_ref i))))))))\n"
- " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
- " ((return (constant vec3 (0.0 0.0))))\n"
- " ((return (expression vec3 -\n"
- " (expression vec3 * (var_ref eta) (var_ref i))\n"
- " (expression vec3 *\n"
- " (expression float +\n"
- " (expression float * (var_ref eta)\n"
- " (expression float dot (var_ref n) (var_ref i)))\n"
- " (expression float sqrt (var_ref k)))\n"
- " (var_ref n))))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 i)\n"
- " (declare (in) vec4 n)\n"
- " (declare (in) float eta))\n"
- " ((declare () float k)\n"
- " (assign (constant bool (1)) (var_ref k)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * (var_ref eta)\n"
- " (expression float * (var_ref eta)\n"
- " (expression float - (constant float (1.0))\n"
- " (expression float * \n"
- " (expression float dot (var_ref n) (var_ref i))\n"
- " (expression float dot (var_ref n) (var_ref i))))))))\n"
- " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
- " ((return (constant vec4 (0.0 0.0))))\n"
- " ((return (expression vec4 -\n"
- " (expression vec4 * (var_ref eta) (var_ref i))\n"
- " (expression vec4 *\n"
- " (expression float +\n"
- " (expression float * (var_ref eta)\n"
- " (expression float dot (var_ref n) (var_ref i)))\n"
- " (expression float sqrt (var_ref k)))\n"
- " (var_ref n))))))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_110_sign = {
- "((function sign\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (expression float sign (var_ref x)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((declare () vec2 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((declare () vec3 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((declare () vec4 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float sign (swiz w (var_ref x))))\n"
- " (return (var_ref t))))\n"
- "))\n"
- "\n"
-};
-
-static const char *builtins_110_sin = {
- "((function sin\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float angle))\n"
- " ((return (expression float sin (var_ref angle)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 angle))\n"
- " ((return (expression vec2 sin (var_ref angle)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 angle))\n"
- " ((return (expression vec3 sin (var_ref angle)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 angle))\n"
- " ((return (expression vec4 sin (var_ref angle)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_smoothstep = {
- "((function smoothstep\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float edge0)\n"
- " (declare (in) float edge1)\n"
- " (declare (in) float x))\n"
- " ((declare () float t)\n"
- "\n"
- " (assign (constant bool (1)) (var_ref t)\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (var_ref x) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (return (expression float * (var_ref t) (expression float * (var_ref t) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (var_ref t))))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) float edge0)\n"
- " (declare (in) float edge1)\n"
- " (declare (in) vec2 x))\n"
- " ((declare () vec2 t)\n"
- " (declare () vec2 retval)\n"
- "\n"
- " (assign (constant bool (1)) (swiz x (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz y (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
- " (return (var_ref retval))\n"
- " ))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) float edge0)\n"
- " (declare (in) float edge1)\n"
- " (declare (in) vec3 x))\n"
- " ((declare () vec3 t)\n"
- " (declare () vec3 retval)\n"
- "\n"
- " (assign (constant bool (1)) (swiz x (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz y (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz z (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
- " (return (var_ref retval))\n"
- " ))\n"
- "\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) float edge0)\n"
- " (declare (in) float edge1)\n"
- " (declare (in) vec4 x))\n"
- " ((declare () vec4 t)\n"
- " (declare () vec4 retval)\n"
- "\n"
- " (assign (constant bool (1)) (swiz x (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz y (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz z (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz w (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz w (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))\n"
- " (return (var_ref retval))\n"
- " ))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 edge0)\n"
- " (declare (in) vec2 edge1)\n"
- " (declare (in) vec2 x))\n"
- " ((declare () vec2 t)\n"
- " (declare () vec2 retval)\n"
- "\n"
- " (assign (constant bool (1)) (swiz x (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz y (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
- " (return (var_ref retval))\n"
- " ))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 edge0)\n"
- " (declare (in) vec3 edge1)\n"
- " (declare (in) vec3 x))\n"
- " ((declare () vec3 t)\n"
- " (declare () vec3 retval)\n"
- "\n"
- " (assign (constant bool (1)) (swiz x (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz y (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz z (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
- " (return (var_ref retval))\n"
- " ))\n"
- "\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 edge0)\n"
- " (declare (in) vec4 edge1)\n"
- " (declare (in) vec4 x))\n"
- " ((declare () vec4 t)\n"
- " (declare () vec4 retval)\n"
- "\n"
- " (assign (constant bool (1)) (swiz x (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz y (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz z (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
- "\n"
- " (assign (constant bool (1)) (swiz w (var_ref t))\n"
- " (expression float max\n"
- " (expression float min\n"
- " (expression float / (expression float - (swiz w (var_ref x)) (swiz w (var_ref edge0))) (expression float - (swiz w (var_ref edge1)) (swiz w (var_ref edge0))))\n"
- " (constant float (1.0)))\n"
- " (constant float (0.0))))\n"
- " (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))\n"
- " (return (var_ref retval))\n"
- " ))\n"
- "\n"
- "))\n"
- "\n"
-};
-
-static const char *builtins_110_sqrt = {
- "((function sqrt\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float arg0))\n"
- " ((return (expression float sqrt (var_ref arg0)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 arg0))\n"
- " ((return (expression vec2 sqrt (var_ref arg0)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 arg0))\n"
- " ((return (expression vec3 sqrt (var_ref arg0)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 arg0))\n"
- " ((return (expression vec4 sqrt (var_ref arg0)))))\n"
- "))\n"
-};
-
-static const char *builtins_110_step = {
- "((function step\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float edge)\n"
- " (declare (in) float x))\n"
- " ((return (expression float b2f (expression bool < (var_ref x) (var_ref edge))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) float edge)\n"
- " (declare (in) vec2 x))\n"
- " ((declare () vec2 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) float edge)\n"
- " (declare (in) vec3 x))\n"
- " ((declare () vec3 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) float edge)\n"
- " (declare (in) vec4 x))\n"
- " ((declare () vec4 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))\n"
- " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(var_ref edge))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 edge)\n"
- " (declare (in) vec2 x))\n"
- " ((declare () vec2 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 edge)\n"
- " (declare (in) vec3 x))\n"
- " ((declare () vec3 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(swiz z (var_ref edge)))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 edge)\n"
- " (declare (in) vec4 x))\n"
- " ((declare () vec4 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz z (var_ref edge)))))\n"
- " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(swiz w (var_ref edge)))))\n"
- " (return (var_ref t))))\n"
- "))\n"
- "\n"
-};
-
-static const char *builtins_110_tan = {
- "((function tan\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float angle))\n"
- " ((return (expression float / (expression float sin (var_ref angle)) (expression float cos (var_ref angle))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 angle))\n"
- " ((return (expression float / (expression float sin (var_ref angle)) (expression vec2 cos (var_ref angle))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 angle))\n"
- " ((return (expression float / (expression float sin (var_ref angle)) (expression vec3 cos (var_ref angle))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 angle))\n"
- " ((return (expression float / (expression float sin (var_ref angle)) (expression vec4 cos (var_ref angle))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_textures = {
- "((function texture1D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) float P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- ")\n"
- " (function texture1DLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function texture1DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- ")\n"
- " (function texture1DProjLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function texture2D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- ")\n"
- "(function texture2DLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function texture2DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- ")\n"
- " (function texture2DProjLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function texture3D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- ")\n"
- " (function texture3DLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function texture3DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- ")\n"
- " (function texture3DProjLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function textureCube\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) samplerCube sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- ")\n"
- " (function textureCubeLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) samplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function shadow1D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DShadow sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
- "\n"
- ")\n"
- " (function shadow1DLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DShadow sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function shadow1DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DShadow sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))\n"
- "\n"
- ")\n"
- " (function shadow1DProjLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DShadow sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function shadow2D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DShadow sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
- "\n"
- ")\n"
- " (function shadow2DLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DShadow sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function shadow2DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DShadow sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))\n"
- "\n"
- ")\n"
- " (function shadow2DProjLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DShadow sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *functions_for_110 [] = {
- builtins_110_abs,
- builtins_110_all,
- builtins_110_any,
- builtins_110_asin,
- builtins_110_atan,
- builtins_110_ceil,
- builtins_110_clamp,
- builtins_110_cos,
- builtins_110_cross,
- builtins_110_degrees,
- builtins_110_distance,
- builtins_110_dot,
- builtins_110_equal,
- builtins_110_exp,
- builtins_110_exp2,
- builtins_110_faceforward,
- builtins_110_floor,
- builtins_110_fract,
- builtins_110_greaterThan,
- builtins_110_greaterThanEqual,
- builtins_110_inversesqrt,
- builtins_110_length,
- builtins_110_lessThan,
- builtins_110_lessThanEqual,
- builtins_110_log,
- builtins_110_log2,
- builtins_110_matrixCompMult,
- builtins_110_max,
- builtins_110_min,
- builtins_110_mix,
- builtins_110_mod,
- builtins_110_noise_fake,
- builtins_110_normalize,
- builtins_110_not,
- builtins_110_notEqual,
- builtins_110_pow,
- builtins_110_radians,
- builtins_110_reflect,
- builtins_110_refract,
- builtins_110_sign,
- builtins_110_sin,
- builtins_110_smoothstep,
- builtins_110_sqrt,
- builtins_110_step,
- builtins_110_tan,
- builtins_110_textures,
-};
-
-/* 110_fs builtins */
-
-static const char *builtins_110_fs_derivatives = {
- "((function dFdx\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float p))\n"
- " ((return (expression float dFdx (var_ref p)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 p))\n"
- " ((return (expression vec2 dFdx (var_ref p)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 p))\n"
- " ((return (expression vec3 dFdx (var_ref p)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 p))\n"
- " ((return (expression vec4 dFdx (var_ref p)))))\n"
- " )\n"
- "\n"
- " (function dFdy\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float p))\n"
- " ((return (expression float dFdy (var_ref p)))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 p))\n"
- " ((return (expression vec2 dFdy (var_ref p)))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 p))\n"
- " ((return (expression vec3 dFdy (var_ref p)))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 p))\n"
- " ((return (expression vec4 dFdy (var_ref p)))))\n"
- " )\n"
- "\n"
- " (function fwidth\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float p))\n"
- " ((return (expression float +\n"
- " (expression float abs (expression float dFdx (var_ref p)))\n"
- " (expression float abs (expression float dFdy (var_ref p)))))))\n"
- "\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 p))\n"
- " ((return (expression vec2 +\n"
- " (expression vec2 abs (expression vec2 dFdx (var_ref p)))\n"
- " (expression vec2 abs (expression vec2 dFdy (var_ref p)))))))\n"
- "\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 p))\n"
- " ((return (expression vec3 +\n"
- " (expression vec3 abs (expression vec3 dFdx (var_ref p)))\n"
- " (expression vec3 abs (expression vec3 dFdy (var_ref p)))))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 p))\n"
- " ((return (expression vec4 +\n"
- " (expression vec4 abs (expression vec4 dFdx (var_ref p)))\n"
- " (expression vec4 abs (expression vec4 dFdy (var_ref p)))))))\n"
- "))\n"
-};
-
-static const char *builtins_110_fs_textures = {
- "((function texture1D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function texture1DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function texture2D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function texture2DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function texture3D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function texture3DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function textureCube\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) samplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function shadow1D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DShadow sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function shadow1DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DShadow sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function shadow2D\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DShadow sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function shadow2DProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DShadow sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *functions_for_110_fs [] = {
- builtins_110_fs_derivatives,
- builtins_110_fs_textures,
-};
-
-/* 110_vs builtins */
-
-static const char *builtins_110_vs_ftransform = {
- "((function ftransform\n"
- " (signature vec4\n"
- " (parameters)\n"
- " ((return (expression vec4 *\n"
- " (var_ref gl_ModelViewProjectionMatrix)\n"
- " (var_ref gl_Vertex)))))\n"
- "))\n"
-};
-
-static const char *functions_for_110_vs [] = {
- builtins_110_vs_ftransform,
-};
-
-/* 120 builtins */
-
-static const char *builtins_120_matrixCompMult = {
- "((function matrixCompMult\n"
- " (signature mat2x3\n"
- " (parameters\n"
- " (declare (in) mat2x3 x)\n"
- " (declare (in) mat2x3 y))\n"
- " ((declare () mat2x3 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- "(return (var_ref z))))\n"
- "\n"
- " (signature mat3x2\n"
- " (parameters\n"
- " (declare (in) mat3x2 x)\n"
- " (declare (in) mat3x2 y))\n"
- " ((declare () mat3x2 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
- "(return (var_ref z))))\n"
- "\n"
- " (signature mat2x4\n"
- " (parameters\n"
- " (declare (in) mat2x4 x)\n"
- " (declare (in) mat2x4 y))\n"
- " ((declare () mat2x4 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- "(return (var_ref z))))\n"
- "\n"
- " (signature mat4x2\n"
- " (parameters\n"
- " (declare (in) mat4x2 x)\n"
- " (declare (in) mat4x2 y))\n"
- " ((declare () mat4x2 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec2 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3))))) \n"
- "(return (var_ref z))))\n"
- "\n"
- " (signature mat3x4\n"
- " (parameters\n"
- " (declare (in) mat3x4 x)\n"
- " (declare (in) mat3x4 y))\n"
- " ((declare () mat3x4 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
- "(return (var_ref z))))\n"
- "\n"
- " (signature mat4x3\n"
- " (parameters\n"
- " (declare (in) mat4x3 x)\n"
- " (declare (in) mat4x3 y))\n"
- " ((declare () mat4x3 z)\n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec3 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3))))) \n"
- "(return (var_ref z))))\n"
- "))\n"
-};
-
-static const char *builtins_120_outerProduct = {
- "((function outerProduct\n"
- " (signature mat2\n"
- " (parameters\n"
- " (declare (in) vec2 u)\n"
- " (declare (in) vec2 v))\n"
- " ((declare () mat2 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat2x3\n"
- " (parameters\n"
- " (declare (in) vec2 u)\n"
- " (declare (in) vec3 v))\n"
- " ((declare () mat2x3 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat2x4\n"
- " (parameters\n"
- " (declare (in) vec2 u)\n"
- " (declare (in) vec4 v))\n"
- " ((declare () mat2x4 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat3x2\n"
- " (parameters\n"
- " (declare (in) vec3 u)\n"
- " (declare (in) vec2 v))\n"
- " ((declare () mat3x2 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat3\n"
- " (parameters\n"
- " (declare (in) vec3 u)\n"
- " (declare (in) vec3 v))\n"
- " ((declare () mat3 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat3x4\n"
- " (parameters\n"
- " (declare (in) vec3 u)\n"
- " (declare (in) vec4 v))\n"
- " ((declare () mat3x4 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat4x2\n"
- " (parameters\n"
- " (declare (in) vec4 u)\n"
- " (declare (in) vec2 v))\n"
- " ((declare () mat4x2 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec2 * (var_ref v) (swiz w (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat4x3\n"
- " (parameters\n"
- " (declare (in) vec4 u)\n"
- " (declare (in) vec3 v))\n"
- " ((declare () mat4x3 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec3 * (var_ref v) (swiz w (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "\n"
- " (signature mat4\n"
- " (parameters\n"
- " (declare (in) vec4 u)\n"
- " (declare (in) vec4 v))\n"
- " ((declare () mat4 m)\n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u)))) \n"
- " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec4 * (var_ref v) (swiz w (var_ref u)))) \n"
- "(return (var_ref m))))\n"
- "))\n"
- "\n"
-};
-
-static const char *builtins_120_transpose = {
- "((function transpose\n"
- " (signature mat2\n"
- " (parameters\n"
- " (declare (in) mat2 m))\n"
- " ((declare () mat2 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat3x2\n"
- " (parameters\n"
- " (declare (in) mat2x3 m))\n"
- " ((declare () mat3x2 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat4x2\n"
- " (parameters\n"
- " (declare (in) mat2x4 m))\n"
- " ((declare () mat4x2 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat2x3\n"
- " (parameters\n"
- " (declare (in) mat3x2 m))\n"
- " ((declare () mat2x3 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat3\n"
- " (parameters\n"
- " (declare (in) mat3 m))\n"
- " ((declare () mat3 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat4x3\n"
- " (parameters\n"
- " (declare (in) mat3x4 m))\n"
- " ((declare () mat4x3 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat2x4\n"
- " (parameters\n"
- " (declare (in) mat4x2 m))\n"
- " ((declare () mat2x4 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat3x4\n"
- " (parameters\n"
- " (declare (in) mat4x3 m))\n"
- " ((declare () mat3x4 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3))))) \n"
- "(return (var_ref t))))\n"
- "\n"
- " (signature mat4\n"
- " (parameters\n"
- " (declare (in) mat4 m))\n"
- " ((declare () mat4 t)\n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3))))) \n"
- " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (3))))) \n"
- "(return (var_ref t))))\n"
- ")\n"
- "\n"
- ")\n"
- "\n"
-};
-
-static const char *functions_for_120 [] = {
- builtins_120_matrixCompMult,
- builtins_120_outerProduct,
- builtins_120_transpose,
-};
-
-/* 130 builtins */
-
-static const char *builtins_130_clamp = {
- "((function clamp\n"
- " (signature int\n"
- " (parameters\n"
- " (declare (in) int arg0)\n"
- " (declare (in) int arg1)\n"
- " (declare (in) int arg2))\n"
- " ((return (expression int max (expression int min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1)\n"
- " (declare (in) ivec2 arg2))\n"
- " ((return (expression ivec2 max (expression ivec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1)\n"
- " (declare (in) ivec3 arg2))\n"
- " ((return (expression ivec3 max (expression ivec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1)\n"
- " (declare (in) ivec4 arg2))\n"
- " ((return (expression ivec4 max (expression ivec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) int arg1)\n"
- " (declare (in) int arg2))\n"
- " ((declare () ivec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature ivec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) int arg1)\n"
- " (declare (in) int arg2))\n"
- " ((declare () ivec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) int arg1)\n"
- " (declare (in) int arg2))\n"
- " ((declare () ivec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uint\n"
- " (parameters\n"
- " (declare (in) uint arg0)\n"
- " (declare (in) uint arg1)\n"
- " (declare (in) uint arg2))\n"
- " ((return (expression uint max (expression uint min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1)\n"
- " (declare (in) uvec2 arg2))\n"
- " ((return (expression uvec2 max (expression uvec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1)\n"
- " (declare (in) uvec3 arg2))\n"
- " ((return (expression uvec3 max (expression uvec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1)\n"
- " (declare (in) uvec4 arg2))\n"
- " ((return (expression uvec4 max (expression uvec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uint arg1)\n"
- " (declare (in) uint arg2))\n"
- " ((declare () uvec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uint arg1)\n"
- " (declare (in) uint arg2))\n"
- " ((declare () uvec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uint arg1)\n"
- " (declare (in) uint arg2))\n"
- " ((declare () uvec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "))\n"
-};
-
-static const char *builtins_130_cosh = {
- "((function cosh\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (expression float * (constant float (0.5))\n"
- " (expression float +\n"
- " (expression float exp (var_ref x))\n"
- " (expression float exp (expression float neg (var_ref x))))))))\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (expression vec2 * (constant vec2 (0.5))\n"
- " (expression vec2 +\n"
- " (expression vec2 exp (var_ref x))\n"
- " (expression vec2 exp (expression vec2 neg (var_ref x))))))))\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (expression vec3 * (constant vec3 (0.5))\n"
- " (expression vec3 +\n"
- " (expression vec3 exp (var_ref x))\n"
- " (expression vec3 exp (expression vec3 neg (var_ref x))))))))\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (expression vec4 * (constant vec4 (0.5))\n"
- " (expression vec4 +\n"
- " (expression vec4 exp (var_ref x))\n"
- " (expression vec4 exp (expression vec4 neg (var_ref x))))))))\n"
- "))\n"
-};
-
-static const char *builtins_130_equal = {
- "((function equal\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_130_greaterThan = {
- "((function greaterThan\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_130_greaterThanEqual = {
- "((function greaterThanEqual\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_130_lessThan = {
- "((function lessThan\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_130_lessThanEqual = {
- "((function lessThanEqual\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_130_max = {
- "((function max\n"
- " (signature int\n"
- " (parameters\n"
- " (declare (in) int arg0)\n"
- " (declare (in) int arg1))\n"
- " ((return (expression int max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((return (expression ivec2 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((return (expression ivec3 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((return (expression ivec4 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) int arg1))\n"
- " ((declare () ivec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature ivec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) int arg1))\n"
- " ((declare () ivec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) int arg1))\n"
- " ((declare () ivec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result))\n"
- " (expression int max (swiz w (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uint\n"
- " (parameters\n"
- " (declare (in) uint arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((return (expression uint max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((return (expression uvec2 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((return (expression uvec3 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((return (expression uvec4 max (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((declare () uvec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((declare () uvec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((declare () uvec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result))\n"
- " (expression uint max (swiz w (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "))\n"
-};
-
-static const char *builtins_130_min = {
- "((function min\n"
- " (signature int\n"
- " (parameters\n"
- " (declare (in) int arg0)\n"
- " (declare (in) int arg1))\n"
- " ((return (expression int min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) ivec2 arg1))\n"
- " ((return (expression ivec2 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) ivec3 arg1))\n"
- " ((return (expression ivec3 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) ivec4 arg1))\n"
- " ((return (expression ivec4 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature ivec2\n"
- " (parameters\n"
- " (declare (in) ivec2 arg0)\n"
- " (declare (in) int arg1))\n"
- " ((declare () ivec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature ivec3\n"
- " (parameters\n"
- " (declare (in) ivec3 arg0)\n"
- " (declare (in) int arg1))\n"
- " ((declare () ivec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) ivec4 arg0)\n"
- " (declare (in) int arg1))\n"
- " ((declare () ivec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result))\n"
- " (expression int min (swiz w (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uint\n"
- " (parameters\n"
- " (declare (in) uint arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((return (expression uint min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((return (expression uvec2 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((return (expression uvec3 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((return (expression uvec4 min (var_ref arg0) (var_ref arg1)))))\n"
- "\n"
- " (signature uvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((declare () uvec2 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((declare () uvec3 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uint arg1))\n"
- " ((declare () uvec4 result)\n"
- " (assign (constant bool (1)) (swiz x (var_ref result))\n"
- " (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz y (var_ref result))\n"
- " (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz z (var_ref result))\n"
- " (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
- " (assign (constant bool (1)) (swiz w (var_ref result))\n"
- " (expression uint min (swiz w (var_ref arg0)) (var_ref arg1)))\n"
- " (return (var_ref result))))\n"
- "))\n"
-};
-
-static const char *builtins_130_notEqual = {
- "((function notEqual\n"
- " (signature bvec2\n"
- " (parameters\n"
- " (declare (in) uvec2 arg0)\n"
- " (declare (in) uvec2 arg1))\n"
- " ((declare () bvec2 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec3\n"
- " (parameters\n"
- " (declare (in) uvec3 arg0)\n"
- " (declare (in) uvec3 arg1))\n"
- " ((declare () bvec3 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "\n"
- " (signature bvec4\n"
- " (parameters\n"
- " (declare (in) uvec4 arg0)\n"
- " (declare (in) uvec4 arg1))\n"
- " ((declare () bvec4 temp)\n"
- " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
- " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool != (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
- " (return (var_ref temp))))\n"
- "))\n"
-};
-
-static const char *builtins_130_sign = {
- "((function sign\n"
- " (signature int\n"
- " (parameters\n"
- " (declare (in) int x))\n"
- " ((return (expression int / (var_ref x) (expression int abs (var_ref x))))))\n"
- "\n"
- " (signature ivec2\n"
- " (parameters\n"
- " (declare (in) ivec2 x))\n"
- " ((declare () ivec2 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature ivec3\n"
- " (parameters\n"
- " (declare (in) ivec3 x))\n"
- " ((declare () ivec3 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))\n"
- " (return (var_ref t))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) ivec4 x))\n"
- " ((declare () ivec4 t)\n"
- " (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))\n"
- " (assign (constant bool (1)) (swiz w (var_ref t)) (expression int sign (swiz w (var_ref x))))\n"
- " (return (var_ref t))))\n"
- "))\n"
- "\n"
-};
-
-static const char *builtins_130_sinh = {
- "((function sinh\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (expression float * (constant float (0.5))\n"
- " (expression float -\n"
- " (expression float exp (var_ref x))\n"
- " (expression float exp (expression float neg (var_ref x))))))))\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (expression vec2 * (constant vec2 (0.5))\n"
- " (expression vec2 -\n"
- " (expression vec2 exp (var_ref x))\n"
- " (expression vec2 exp (expression vec2 neg (var_ref x))))))))\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (expression vec3 * (constant vec3 (0.5))\n"
- " (expression vec3 -\n"
- " (expression vec3 exp (var_ref x))\n"
- " (expression vec3 exp (expression vec3 neg (var_ref x))))))))\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (expression vec4 * (constant vec4 (0.5))\n"
- " (expression vec4 -\n"
- " (expression vec4 exp (var_ref x))\n"
- " (expression vec4 exp (expression vec4 neg (var_ref x))))))))\n"
- "))\n"
-};
-
-static const char *builtins_130_tanh = {
- "((function tanh\n"
- " (signature float\n"
- " (parameters\n"
- " (declare (in) float x))\n"
- " ((return (expression float /\n"
- " (expression float -\n"
- " (expression float exp (var_ref x))\n"
- " (expression float exp (expression float neg (var_ref x))))\n"
- " (expression float +\n"
- " (expression float exp (var_ref x))\n"
- " (expression float exp (expression float neg (var_ref x))))))))\n"
- " (signature vec2\n"
- " (parameters\n"
- " (declare (in) vec2 x))\n"
- " ((return (expression vec2 /\n"
- " (expression vec2 -\n"
- " (expression vec2 exp (var_ref x))\n"
- " (expression vec2 exp (expression vec2 neg (var_ref x))))\n"
- " (expression vec2 +\n"
- " (expression vec2 exp (var_ref x))\n"
- " (expression vec2 exp (expression vec2 neg (var_ref x))))))))\n"
- " (signature vec3\n"
- " (parameters\n"
- " (declare (in) vec3 x))\n"
- " ((return (expression vec3 /\n"
- " (expression vec3 -\n"
- " (expression vec3 exp (var_ref x))\n"
- " (expression vec3 exp (expression vec3 neg (var_ref x))))\n"
- " (expression vec3 +\n"
- " (expression vec3 exp (var_ref x))\n"
- " (expression vec3 exp (expression vec3 neg (var_ref x))))))))\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) vec4 x))\n"
- " ((return (expression vec4 /\n"
- " (expression vec4 -\n"
- " (expression vec4 exp (var_ref x))\n"
- " (expression vec4 exp (expression vec4 neg (var_ref x))))\n"
- " (expression vec4 +\n"
- " (expression vec4 exp (var_ref x))\n"
- " (expression vec4 exp (expression vec4 neg (var_ref x))))))))\n"
- "))\n"
-};
-
-static const char *builtins_130_texelFetch = {
- "((function texelFetch\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) int P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) int P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) int P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) ivec2 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) ivec2 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) ivec2 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) ivec3 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) ivec3 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) ivec3 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) ivec2 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1DArray sampler)\n"
- " (declare (in) ivec2 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1DArray sampler)\n"
- " (declare (in) ivec2 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) ivec3 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2DArray sampler)\n"
- " (declare (in) ivec3 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2DArray sampler)\n"
- " (declare (in) ivec3 P) \n"
- " (declare (in) int lod) )\n"
- " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_130_texture = {
- "((function texture\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) float P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) float P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) float P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) samplerCube sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isamplerCube sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usamplerCube sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1DArray sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1DArray sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2DArray sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2DArray sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_130_textureGrad = {
- "((function textureGrad\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) samplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isamplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usamplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- ")\n"
- ")\n"
-};
-
-static const char *builtins_130_textureLod = {
- "((function textureLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) samplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isamplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usamplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_130_textureProj = {
- "((function textureProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_130_textureProjGrad = {
- "((function textureLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float dPdx) \n"
- " (declare (in) float dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) vec2 dPdx) \n"
- " (declare (in) vec2 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) vec3 dPdx) \n"
- " (declare (in) vec3 dPdy) )\n"
- " ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_130_textureProjLod = {
- "((function textureLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *functions_for_130 [] = {
- builtins_130_clamp,
- builtins_130_cosh,
- builtins_130_equal,
- builtins_130_greaterThan,
- builtins_130_greaterThanEqual,
- builtins_130_lessThan,
- builtins_130_lessThanEqual,
- builtins_130_max,
- builtins_130_min,
- builtins_130_notEqual,
- builtins_130_sign,
- builtins_130_sinh,
- builtins_130_tanh,
- builtins_130_texelFetch,
- builtins_130_texture,
- builtins_130_textureGrad,
- builtins_130_textureLod,
- builtins_130_textureProj,
- builtins_130_textureProjGrad,
- builtins_130_textureProjLod,
-};
-
-/* 130_fs builtins */
-
-static const char *builtins_130_fs_texture = {
- "((function texture\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) float P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) samplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isamplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usamplerCube sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *builtins_130_fs_textureProj = {
- "((function textureProj\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler1D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler2D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature ivec4\n"
- " (parameters\n"
- " (declare (in) isampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- " (signature uvec4\n"
- " (parameters\n"
- " (declare (in) usampler3D sampler)\n"
- " (declare (in) vec4 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *functions_for_130_fs [] = {
- builtins_130_fs_texture,
- builtins_130_fs_textureProj,
-};
-
-/* ARB_texture_rectangle builtins */
-
-static const char *builtins_ARB_texture_rectangle_textures = {
- "((function texture2DRect\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DRect sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- ")\n"
- " (function shadow2DRect\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DRectShadow sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *functions_for_ARB_texture_rectangle [] = {
- builtins_ARB_texture_rectangle_textures,
-};
-
-/* EXT_texture_array builtins */
-
-static const char *builtins_EXT_texture_array_textures = {
- "((function texture1DArray\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) vec2 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- ")\n"
- " (function texture1DArrayLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function texture2DArray\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
- "\n"
- ")\n"
- " (function texture2DArrayLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function shadow1DArray\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArrayShadow sampler)\n"
- " (declare (in) vec3 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
- "\n"
- ")\n"
- " (function shadow1DArrayLod\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArrayShadow sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float lod) )\n"
- " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))\n"
- "\n"
- ")\n"
- " (function shadow2DArray\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArrayShadow sampler)\n"
- " (declare (in) vec4 P) )\n"
- " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) 1 (swiz w (var_ref P)) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *functions_for_EXT_texture_array [] = {
- builtins_EXT_texture_array_textures,
-};
-
-/* EXT_texture_array_fs builtins */
-
-static const char *builtins_EXT_texture_array_fs_textures = {
- "((function texture1DArray\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArray sampler)\n"
- " (declare (in) vec2 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function texture2DArray\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler2DArray sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
- "\n"
- ")\n"
- " (function shadow1DArray\n"
- " (signature vec4\n"
- " (parameters\n"
- " (declare (in) sampler1DArrayShadow sampler)\n"
- " (declare (in) vec3 P) \n"
- " (declare (in) float bias) )\n"
- " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))\n"
- "\n"
- "))\n"
-};
-
-static const char *functions_for_EXT_texture_array_fs [] = {
- builtins_EXT_texture_array_fs_textures,
-};
-
-void
-_mesa_glsl_initialize_functions(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- if (state->language_version >= 110)
- read_builtins(state, instructions,
- functions_for_110,
- sizeof(functions_for_110) / sizeof(const char *));
-
- if (state->target == fragment_shader && state->language_version >= 110)
- read_builtins(state, instructions,
- functions_for_110_fs,
- sizeof(functions_for_110_fs) / sizeof(const char *));
-
- if (state->target == vertex_shader && state->language_version >= 110)
- read_builtins(state, instructions,
- functions_for_110_vs,
- sizeof(functions_for_110_vs) / sizeof(const char *));
-
- if (state->language_version >= 120)
- read_builtins(state, instructions,
- functions_for_120,
- sizeof(functions_for_120) / sizeof(const char *));
-
- if (state->language_version >= 130)
- read_builtins(state, instructions,
- functions_for_130,
- sizeof(functions_for_130) / sizeof(const char *));
-
- if (state->target == fragment_shader && state->language_version >= 130)
- read_builtins(state, instructions,
- functions_for_130_fs,
- sizeof(functions_for_130_fs) / sizeof(const char *));
-
- if (state->ARB_texture_rectangle_enable)
- read_builtins(state, instructions,
- functions_for_ARB_texture_rectangle,
- sizeof(functions_for_ARB_texture_rectangle) / sizeof(const char *));
-
- if (state->EXT_texture_array_enable)
- read_builtins(state, instructions,
- functions_for_EXT_texture_array,
- sizeof(functions_for_EXT_texture_array) / sizeof(const char *));
-
- if (state->target == fragment_shader && state->EXT_texture_array_enable)
- read_builtins(state, instructions,
- functions_for_EXT_texture_array_fs,
- sizeof(functions_for_EXT_texture_array_fs) / sizeof(const char *));
-
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#ifndef Elements
-#define Elements(x) (sizeof(x)/sizeof(*(x)))
-#endif
-
-static const struct glsl_type _error_type =
- glsl_type(GLSL_TYPE_ERROR, 0, 0, "");
-
-static const struct glsl_type void_type =
- glsl_type(GLSL_TYPE_VOID, 0, 0, "void");
-
-const glsl_type *const glsl_type::error_type = & _error_type;
-
-/** \name Core built-in types
- *
- * These types exist in all versions of GLSL.
- */
-/*@{*/
-
-static const struct glsl_type builtin_core_types[] = {
- glsl_type( GLSL_TYPE_BOOL, 1, 1, "bool"),
- glsl_type( GLSL_TYPE_BOOL, 2, 1, "bvec2"),
- glsl_type( GLSL_TYPE_BOOL, 3, 1, "bvec3"),
- glsl_type( GLSL_TYPE_BOOL, 4, 1, "bvec4"),
- glsl_type( GLSL_TYPE_INT, 1, 1, "int"),
- glsl_type( GLSL_TYPE_INT, 2, 1, "ivec2"),
- glsl_type( GLSL_TYPE_INT, 3, 1, "ivec3"),
- glsl_type( GLSL_TYPE_INT, 4, 1, "ivec4"),
- glsl_type( GLSL_TYPE_FLOAT, 1, 1, "float"),
- glsl_type( GLSL_TYPE_FLOAT, 2, 1, "vec2"),
- glsl_type( GLSL_TYPE_FLOAT, 3, 1, "vec3"),
- glsl_type( GLSL_TYPE_FLOAT, 4, 1, "vec4"),
- glsl_type( GLSL_TYPE_FLOAT, 2, 2, "mat2"),
- glsl_type( GLSL_TYPE_FLOAT, 3, 3, "mat3"),
- glsl_type( GLSL_TYPE_FLOAT, 4, 4, "mat4"),
- glsl_type( GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT, "sampler1D"),
- glsl_type( GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT, "sampler1DShadow"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT, "sampler2D"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT, "sampler2DShadow"),
- glsl_type( GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT, "sampler3D"),
- glsl_type(GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT, "samplerCube"),
-};
-
-const glsl_type *const glsl_type::bool_type = & builtin_core_types[0];
-const glsl_type *const glsl_type::int_type = & builtin_core_types[4];
-const glsl_type *const glsl_type::ivec4_type = & builtin_core_types[7];
-const glsl_type *const glsl_type::float_type = & builtin_core_types[8];
-const glsl_type *const glsl_type::vec2_type = & builtin_core_types[9];
-const glsl_type *const glsl_type::vec3_type = & builtin_core_types[10];
-const glsl_type *const glsl_type::vec4_type = & builtin_core_types[11];
-const glsl_type *const glsl_type::mat2_type = & builtin_core_types[12];
-const glsl_type *const glsl_type::mat3_type = & builtin_core_types[13];
-const glsl_type *const glsl_type::mat4_type = & builtin_core_types[14];
-/*@}*/
-
-/** \name GLSL structures that have not been deprecated.
- */
-/*@{*/
-
-static const struct glsl_struct_field gl_DepthRangeParameters_fields[] = {
- { glsl_type::float_type, "near" },
- { glsl_type::float_type, "far" },
- { glsl_type::float_type, "diff" },
-};
-
-static const struct glsl_type builtin_structure_types[] = {
- glsl_type(gl_DepthRangeParameters_fields,
- Elements(gl_DepthRangeParameters_fields),
- "gl_DepthRangeParameters"),
-};
-/*@}*/
-
-/** \name GLSL 1.00 / 1.10 structures that are deprecated in GLSL 1.30
- */
-/*@{*/
-
-static const struct glsl_struct_field gl_PointParameters_fields[] = {
- { glsl_type::float_type, "size" },
- { glsl_type::float_type, "sizeMin" },
- { glsl_type::float_type, "sizeMax" },
- { glsl_type::float_type, "fadeThresholdSize" },
- { glsl_type::float_type, "distanceConstantAttenuation" },
- { glsl_type::float_type, "distanceLinearAttenuation" },
- { glsl_type::float_type, "distanceQuadraticAttenuation" },
-};
-
-static const struct glsl_struct_field gl_MaterialParameters_fields[] = {
- { glsl_type::vec4_type, "emission" },
- { glsl_type::vec4_type, "ambient" },
- { glsl_type::vec4_type, "diffuse" },
- { glsl_type::vec4_type, "specular" },
- { glsl_type::float_type, "shininess" },
-};
-
-static const struct glsl_struct_field gl_LightSourceParameters_fields[] = {
- { glsl_type::vec4_type, "ambient" },
- { glsl_type::vec4_type, "diffuse" },
- { glsl_type::vec4_type, "specular" },
- { glsl_type::vec4_type, "position" },
- { glsl_type::vec4_type, "halfVector" },
- { glsl_type::vec3_type, "spotDirection" },
- { glsl_type::float_type, "spotExponent" },
- { glsl_type::float_type, "spotCutoff" },
- { glsl_type::float_type, "spotCosCutoff" },
- { glsl_type::float_type, "constantAttenuation" },
- { glsl_type::float_type, "linearAttenuation" },
- { glsl_type::float_type, "quadraticAttenuation" },
-};
-
-static const struct glsl_struct_field gl_LightModelParameters_fields[] = {
- { glsl_type::vec4_type, "ambient" },
-};
-
-static const struct glsl_struct_field gl_LightModelProducts_fields[] = {
- { glsl_type::vec4_type, "sceneColor" },
-};
-
-static const struct glsl_struct_field gl_LightProducts_fields[] = {
- { glsl_type::vec4_type, "ambient" },
- { glsl_type::vec4_type, "diffuse" },
- { glsl_type::vec4_type, "specular" },
-};
-
-static const struct glsl_struct_field gl_FogParameters_fields[] = {
- { glsl_type::vec4_type, "color" },
- { glsl_type::float_type, "density" },
- { glsl_type::float_type, "start" },
- { glsl_type::float_type, "end" },
- { glsl_type::float_type, "scale" },
-};
-
-static const struct glsl_type builtin_110_deprecated_structure_types[] = {
- glsl_type(gl_PointParameters_fields,
- Elements(gl_PointParameters_fields),
- "gl_PointParameters"),
- glsl_type(gl_MaterialParameters_fields,
- Elements(gl_MaterialParameters_fields),
- "gl_MaterialParameters"),
- glsl_type(gl_LightSourceParameters_fields,
- Elements(gl_LightSourceParameters_fields),
- "gl_LightSourceParameters"),
- glsl_type(gl_LightModelParameters_fields,
- Elements(gl_LightModelParameters_fields),
- "gl_LightModelParameters"),
- glsl_type(gl_LightModelProducts_fields,
- Elements(gl_LightModelProducts_fields),
- "gl_LightModelProducts"),
- glsl_type(gl_LightProducts_fields,
- Elements(gl_LightProducts_fields),
- "gl_LightProducts"),
- glsl_type(gl_FogParameters_fields,
- Elements(gl_FogParameters_fields),
- "gl_FogParameters"),
-};
-/*@}*/
-
-/** \name Types added in GLSL 1.20
- */
-/*@{*/
-
-static const struct glsl_type builtin_120_types[] = {
- glsl_type( GLSL_TYPE_FLOAT, 3, 2, "mat2x3"),
- glsl_type( GLSL_TYPE_FLOAT, 4, 2, "mat2x4"),
- glsl_type( GLSL_TYPE_FLOAT, 2, 3, "mat3x2"),
- glsl_type( GLSL_TYPE_FLOAT, 4, 3, "mat3x4"),
- glsl_type( GLSL_TYPE_FLOAT, 2, 4, "mat4x2"),
- glsl_type( GLSL_TYPE_FLOAT, 3, 4, "mat4x3"),
-};
-const glsl_type *const glsl_type::mat2x3_type = & builtin_120_types[0];
-const glsl_type *const glsl_type::mat2x4_type = & builtin_120_types[1];
-const glsl_type *const glsl_type::mat3x2_type = & builtin_120_types[2];
-const glsl_type *const glsl_type::mat3x4_type = & builtin_120_types[3];
-const glsl_type *const glsl_type::mat4x2_type = & builtin_120_types[4];
-const glsl_type *const glsl_type::mat4x3_type = & builtin_120_types[5];
-/*@}*/
-
-/** \name Types added in GLSL 1.30
- */
-/*@{*/
-
-static const struct glsl_type builtin_130_types[] = {
- glsl_type( GLSL_TYPE_UINT, 1, 1, "uint"),
- glsl_type( GLSL_TYPE_UINT, 2, 1, "uvec2"),
- glsl_type( GLSL_TYPE_UINT, 3, 1, "uvec3"),
- glsl_type( GLSL_TYPE_UINT, 4, 1, "uvec4"),
-
- /* 1D and 2D texture arrays */
- glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT, "sampler1DArray"),
- glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT, "isampler1DArray"),
- glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT, "usampler1DArray"),
- glsl_type( GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT, "sampler1DArrayShadow"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT, "sampler2DArray"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT, "isampler2DArray"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT, "usampler2DArray"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT, "sampler2DArrayShadow"),
-
- /* cube shadow samplers */
- glsl_type(GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT, "samplerCubeShadow"),
-
- /* signed and unsigned integer samplers */
- glsl_type( GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT, "isampler1D"),
- glsl_type( GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT, "usampler1D"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT, "isampler2D"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT, "usampler2D"),
- glsl_type( GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT, "isampler3D"),
- glsl_type( GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT, "usampler3D"),
- glsl_type(GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT, "isamplerCube"),
- glsl_type(GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT, "usamplerCube"),
-};
-
-const glsl_type *const glsl_type::uint_type = & builtin_130_types[0];
-const glsl_type *const glsl_type::uvec4_type = & builtin_130_types[3];
-/*@}*/
-
-/** \name Sampler types added by GL_ARB_texture_rectangle
- */
-/*@{*/
-
-static const struct glsl_type builtin_ARB_texture_rectangle_types[] = {
- glsl_type(GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT, "sampler2DRect"),
- glsl_type(GLSL_SAMPLER_DIM_RECT, 1, 0, GLSL_TYPE_FLOAT, "sampler2DRectShadow"),
-};
-/*@}*/
-
-/** \name Sampler types added by GL_EXT_texture_array
- */
-/*@{*/
-
-static const struct glsl_type builtin_EXT_texture_array_types[] = {
- glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT, "sampler1DArray"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT, "sampler2DArray"),
- glsl_type( GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT, "sampler1DArrayShadow"),
- glsl_type( GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT, "sampler2DArrayShadow"),
-};
-/*@}*/
-
-/** \name Sampler types added by GL_EXT_texture_buffer_object
- */
-/*@{*/
-
-static const struct glsl_type builtin_EXT_texture_buffer_object_types[] = {
- glsl_type( GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT, "samplerBuffer"),
- glsl_type( GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT, "isamplerBuffer"),
- glsl_type( GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT, "usamplerBuffer"),
-};
-/*@}*/
+++ /dev/null
-/*
- * 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 "main/mtypes.h"
-
-struct builtin_variable {
- enum ir_variable_mode mode;
- int slot;
- const char *type;
- const char *name;
-};
-
-static const builtin_variable builtin_core_vs_variables[] = {
- { ir_var_out, VERT_RESULT_HPOS, "vec4", "gl_Position" },
- { ir_var_out, VERT_RESULT_PSIZ, "float", "gl_PointSize" },
-};
-
-static const builtin_variable builtin_core_fs_variables[] = {
- { ir_var_in, FRAG_ATTRIB_WPOS, "vec4", "gl_FragCoord" },
- { ir_var_in, FRAG_ATTRIB_FACE, "bool", "gl_FrontFacing" },
- { ir_var_out, FRAG_RESULT_COLOR, "vec4", "gl_FragColor" },
- { ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" },
-};
-
-static const builtin_variable builtin_110_deprecated_fs_variables[] = {
- { ir_var_in, FRAG_ATTRIB_COL0, "vec4", "gl_Color" },
- { ir_var_in, FRAG_ATTRIB_COL1, "vec4", "gl_SecondaryColor" },
- { ir_var_in, FRAG_ATTRIB_FOGC, "float", "gl_FogFragCoord" },
-};
-
-static const builtin_variable builtin_110_deprecated_vs_variables[] = {
- { ir_var_in, VERT_ATTRIB_POS, "vec4", "gl_Vertex" },
- { ir_var_in, VERT_ATTRIB_NORMAL, "vec3", "gl_Normal" },
- { ir_var_in, VERT_ATTRIB_COLOR0, "vec4", "gl_Color" },
- { ir_var_in, VERT_ATTRIB_COLOR1, "vec4", "gl_SecondaryColor" },
- { ir_var_in, VERT_ATTRIB_TEX0, "vec4", "gl_MultiTexCoord0" },
- { ir_var_in, VERT_ATTRIB_TEX1, "vec4", "gl_MultiTexCoord1" },
- { ir_var_in, VERT_ATTRIB_TEX2, "vec4", "gl_MultiTexCoord2" },
- { ir_var_in, VERT_ATTRIB_TEX3, "vec4", "gl_MultiTexCoord3" },
- { ir_var_in, VERT_ATTRIB_TEX4, "vec4", "gl_MultiTexCoord4" },
- { ir_var_in, VERT_ATTRIB_TEX5, "vec4", "gl_MultiTexCoord5" },
- { ir_var_in, VERT_ATTRIB_TEX6, "vec4", "gl_MultiTexCoord6" },
- { ir_var_in, VERT_ATTRIB_TEX7, "vec4", "gl_MultiTexCoord7" },
- { ir_var_in, VERT_ATTRIB_FOG, "float", "gl_FogCoord" },
- { ir_var_out, VERT_RESULT_HPOS, "vec4", "gl_ClipVertex" },
- { ir_var_out, VERT_RESULT_COL0, "vec4", "gl_FrontColor" },
- { ir_var_out, VERT_RESULT_BFC0, "vec4", "gl_BackColor" },
- { ir_var_out, VERT_RESULT_COL1, "vec4", "gl_FrontSecondaryColor" },
- { ir_var_out, VERT_RESULT_BFC1, "vec4", "gl_BackSecondaryColor" },
- { ir_var_out, VERT_RESULT_FOGC, "float", "gl_FogFragCoord" },
-};
-
-static const builtin_variable builtin_130_vs_variables[] = {
- { ir_var_in, -1, "int", "gl_VertexID" },
-};
-
-static const builtin_variable builtin_110_deprecated_uniforms[] = {
- { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrix" },
- { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrix" },
- { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrix" },
- { ir_var_uniform, -1, "mat3", "gl_NormalMatrix" },
- { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverse" },
- { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverse" },
- { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverse" },
- { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixTranspose" },
- { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixTranspose" },
- { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixTranspose" },
- { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverseTranspose" },
- { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverseTranspose" },
- { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverseTranspose" },
- { ir_var_uniform, -1, "float", "gl_NormalScale" },
-};
-
+++ /dev/null
-((function abs
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float abs (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 abs (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 abs (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 abs (var_ref arg0)))))
-))
+++ /dev/null
-((function all
- (signature bool
- (parameters
- (declare (in) bvec2 arg0))
- ((return (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))
-
- (signature bool
- (parameters
- (declare (in) bvec3 arg0))
- ((return (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))
-
- (signature bool
- (parameters
- (declare (in) bvec4 arg0))
- ((return (expression bool && (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))
-))
+++ /dev/null
-((function any
- (signature bool
- (parameters
- (declare (in) bvec2 arg0))
- ((return (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))
-
- (signature bool
- (parameters
- (declare (in) bvec3 arg0))
- ((return (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))
-
- (signature bool
- (parameters
- (declare (in) bvec4 arg0))
- ((return (expression bool || (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))
-))
+++ /dev/null
-((function asin
- (signature float
- (parameters
- (declare (in) float x))
- ((return (expression float *
- (expression float -
- (expression float *
- (constant float (3.1415926))
- (constant float (0.5)))
- (expression float sqrt
- (expression float -
- (constant float (1.0))
- (expression float abs (var_ref x)))))
- (expression float +
- (constant float (1.5707288))
- (expression float *
- (expression float abs (var_ref x))
- (expression float +
- (constant float (-0.2121144))
- (expression float *
- (constant float (0.0742610))
- (expression float abs (var_ref x))))))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((return (expression vec2 *
- (expression float -
- (expression float *
- (constant float (3.1415926))
- (constant float (0.5)))
- (expression vec2 sqrt
- (expression vec2 -
- (constant float (1.0))
- (expression vec2 abs (var_ref x)))))
- (expression vec2 +
- (constant float (1.5707288))
- (expression vec2 *
- (expression vec2 abs (var_ref x))
- (expression vec2 +
- (constant float (-0.2121144))
- (expression vec2 *
- (constant float (0.0742610))
- (expression vec2 abs (var_ref x))))))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((return (expression vec3 *
- (expression vec3 -
- (expression float *
- (constant float (3.1415926))
- (constant float (0.5)))
- (expression vec3 sqrt
- (expression vec3 -
- (constant float (1.0))
- (expression vec3 abs (var_ref x)))))
- (expression vec3 +
- (constant float (1.5707288))
- (expression vec3 *
- (expression vec3 abs (var_ref x))
- (expression vec3 +
- (constant float (-0.2121144))
- (expression vec3 *
- (constant float (0.0742610))
- (expression vec3 abs (var_ref x))))))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((return (expression vec4 *
- (expression vec4 -
- (expression float *
- (constant float (3.1415926))
- (constant float (0.5)))
- (expression vec4 sqrt
- (expression vec4 -
- (constant float (1.0))
- (expression vec4 abs (var_ref x)))))
- (expression vec4 +
- (constant float (1.5707288))
- (expression vec4 *
- (expression vec4 abs (var_ref x))
- (expression vec4 +
- (constant float (-0.2121144))
- (expression vec4 *
- (constant float (0.0742610))
- (expression vec4 abs (var_ref x))))))))))
-)
-
- (function acos
- (signature float
- (parameters
- (declare (in) float x))
- ((return (expression float - (constant float (1.5707963))
- (call asin ((var_ref x)))))))
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((return (expression vec2 - (constant float (1.5707963))
- (call asin ((var_ref x)))))))
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((return (expression vec3 - (constant float (1.5707963))
- (call asin ((var_ref x)))))))
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((return (expression vec4 - (constant float (1.5707963))
- (call asin ((var_ref x)))))))
-))
+++ /dev/null
-((function atan
- (signature float
- (parameters
- (declare (in) float x))
- ((return (call asin ((expression float *
- (var_ref x)
- (expression float rsq
- (expression float +
- (expression float *
- (var_ref x)
- (var_ref x))
- (constant float (1.0))))))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 y_over_x))
- ((return (call asin ((expression vec2 *
- (var_ref y_over_x)
- (expression vec2 rsq
- (expression vec2 +
- (expression vec2 *
- (var_ref y_over_x)
- (var_ref y_over_x))
- (constant float (1.0))))))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 y_over_x))
- ((return (call asin ((expression vec3 *
- (var_ref y_over_x)
- (expression vec3 rsq
- (expression vec3 +
- (expression vec3 *
- (var_ref y_over_x)
- (var_ref y_over_x))
- (constant float (1.0))))))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 y_over_x))
- ((return (call asin ((expression vec4 *
- (var_ref y_over_x)
- (expression vec4 rsq
- (expression vec4 +
- (expression vec4 *
- (var_ref y_over_x)
- (var_ref y_over_x))
- (constant float (1.0))))))))))
-
- (signature float
- (parameters
- (declare (in) float y)
- (declare (in) float x))
- ((declare () float r)
- (if (expression bool >
- (expression float abs (var_ref x))
- (constant float (.0001)))
- ((assign (constant bool (1))
- (var_ref r) (call atan ((expression float /
- (var_ref y)
- (var_ref x)))))
- (if (expression bool <
- (var_ref x)
- (constant float (0.0)))
- ((assign (constant bool (1))
- (var_ref r)
- (expression float +
- (var_ref r)
- (expression float *
- (expression int sign (var_ref y))
- (constant float (3.1415926))))))
- ()))
- ())
- (return (var_ref r))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 y)
- (declare (in) vec2 x))
- ((declare () vec2 r)
- (if (expression bool >
- (expression vec2 abs (var_ref x))
- (constant float (.0001)))
- ((assign (constant bool (1))
- (var_ref r) (call atan ((expression vec2 /
- (var_ref y)
- (var_ref x)))))
- (if (expression bool <
- (var_ref x)
- (constant float (0.0)))
- ((assign (constant bool (1))
- (var_ref r)
- (expression vec2 +
- (var_ref r)
- (expression vec2 *
- (expression int sign (var_ref y))
- (constant float (3.1415926))))))
- ()))
- ())
- (return (var_ref r))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 y)
- (declare (in) vec3 x))
- ((declare () vec3 r)
- (if (expression bool >
- (expression vec3 abs (var_ref x))
- (constant float (.0001)))
- ((assign (constant bool (1))
- (var_ref r) (call atan ((expression vec3 /
- (var_ref y)
- (var_ref x)))))
- (if (expression bool <
- (var_ref x)
- (constant float (0.0)))
- ((assign (constant bool (1))
- (var_ref r)
- (expression vec3 +
- (var_ref r)
- (expression vec3 *
- (expression int sign (var_ref y))
- (constant float (3.1415926))))))
- ()))
- ())
- (return (var_ref r))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 y)
- (declare (in) vec4 x))
- ((declare () vec4 r)
- (if (expression bool >
- (expression vec4 abs (var_ref x))
- (constant float (.0001)))
- ((assign (constant bool (1))
- (var_ref r) (call atan ((expression vec4 /
- (var_ref y)
- (var_ref x)))))
- (if (expression bool <
- (var_ref x)
- (constant float (0.0)))
- ((assign (constant bool (1))
- (var_ref r)
- (expression vec4 +
- (var_ref r)
- (expression vec4 *
- (expression int sign (var_ref y))
- (constant float (3.1415926))))))
- ()))
- ())
- (return (var_ref r))))
-
-))
+++ /dev/null
-((function ceil
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float ceil (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 ceil (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 ceil (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 ceil (var_ref arg0)))))
-))
+++ /dev/null
-((function clamp
- (signature float
- (parameters
- (declare (in) float arg0)
- (declare (in) float arg1)
- (declare (in) float arg2))
- ((return (expression float max (expression float min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1)
- (declare (in) vec2 arg2))
- ((return (expression vec2 max (expression vec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1)
- (declare (in) vec3 arg2))
- ((return (expression vec3 max (expression vec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1)
- (declare (in) vec4 arg2))
- ((return (expression vec4 max (expression vec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) float arg1)
- (declare (in) float arg2))
- ((declare () vec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) float arg1)
- (declare (in) float arg2))
- ((declare () vec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) float arg1)
- (declare (in) float arg2))
- ((declare () vec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result)) (expression vec4 max (expression vec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-))
+++ /dev/null
-((function cos
- (signature float
- (parameters
- (declare (in) float angle))
- ((return (expression float cos (var_ref angle)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 angle))
- ((return (expression vec2 cos (var_ref angle)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 angle))
- ((return (expression vec3 cos (var_ref angle)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 angle))
- ((return (expression vec4 cos (var_ref angle)))))
-))
+++ /dev/null
-((function cross
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((declare () vec3 t)
- (assign (constant bool (1)) (swiz x (var_ref t))
- (expression float - (expression float * (swiz y (var_ref arg0)) (swiz z (var_ref arg1)))
- (expression float * (swiz y (var_ref arg1)) (swiz z (var_ref arg0)))))
- (assign (constant bool (1)) (swiz y (var_ref t))
- (expression float - (expression float * (swiz z (var_ref arg0)) (swiz x (var_ref arg1)))
- (expression float * (swiz z (var_ref arg1)) (swiz x (var_ref arg0)))))
- (assign (constant bool (1)) (swiz z (var_ref t))
- (expression float - (expression float * (swiz x (var_ref arg0)) (swiz y (var_ref arg1)))
- (expression float * (swiz x (var_ref arg1)) (swiz y (var_ref arg0)))))
- (return (var_ref t))))
-))
+++ /dev/null
-((function degrees
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float * (var_ref arg0) (constant float (57.295780))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 * (var_ref arg0) (constant float (57.295780))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 * (var_ref arg0) (constant float (57.295780))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 * (var_ref arg0) (constant float (57.295780))))))
-))
+++ /dev/null
-((function distance
- (signature float
- (parameters
- (declare (in) float p0)
- (declare (in) float p1))
- ((declare () float p)
- (assign (constant bool (1)) (var_ref p) (expression float - (var_ref p0) (var_ref p1)))
- (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
-
- (signature float
- (parameters
- (declare (in) vec2 p0)
- (declare (in) vec2 p1))
- ((declare () vec2 p)
- (assign (constant bool (1)) (var_ref p) (expression vec2 - (var_ref p0) (var_ref p1)))
- (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
-
- (signature float
- (parameters
- (declare (in) vec3 p0)
- (declare (in) vec3 p1))
- ((declare () vec3 p)
- (assign (constant bool (1)) (var_ref p) (expression vec3 - (var_ref p0) (var_ref p1)))
- (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
-
- (signature float
- (parameters
- (declare (in) vec4 p0)
- (declare (in) vec4 p1))
- ((declare () vec4 p)
- (assign (constant bool (1)) (var_ref p) (expression vec4 - (var_ref p0) (var_ref p1)))
- (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
-))
+++ /dev/null
-((function dot
- (signature float
- (parameters
- (declare (in) float arg0)
- (declare (in) float arg1))
- ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
-
- (signature float
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
-
- (signature float
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
-
- (signature float
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
-))
+++ /dev/null
-((function equal
- (signature bvec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function exp
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float exp (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 exp (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 exp (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 exp (var_ref arg0)))))
-))
+++ /dev/null
-((function exp2
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float exp2 (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 exp2 (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 exp2 (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 exp2 (var_ref arg0)))))
-))
+++ /dev/null
-((function faceforward
- (signature float
- (parameters
- (declare (in) float N)
- (declare (in) float I)
- (declare (in) float Nref))
- ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
- ((return (var_ref N)))
- ((return (expression float neg (var_ref N)))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 N)
- (declare (in) vec2 I)
- (declare (in) vec2 Nref))
- ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
- ((return (var_ref N)))
- ((return (expression vec2 neg (var_ref N)))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 N)
- (declare (in) vec3 I)
- (declare (in) vec3 Nref))
- ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
- ((return (var_ref N)))
- ((return (expression vec3 neg (var_ref N)))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 N)
- (declare (in) vec4 I)
- (declare (in) vec4 Nref))
- ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
- ((return (var_ref N)))
- ((return (expression vec4 neg (var_ref N)))))))
-))
+++ /dev/null
-((function floor
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float floor (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 floor (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 floor (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 floor (var_ref arg0)))))
-))
+++ /dev/null
-((function fract
- (signature float
- (parameters
- (declare (in) float x))
- ((return (expression float - (var_ref x) (expression float floor (var_ref x))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((declare () vec2 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))
- (return (var_ref t))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((declare () vec3 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))
- (return (var_ref t))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((declare () vec4 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))
- (assign (constant bool (1)) (swiz w (var_ref t)) (expression float - (swiz w (var_ref x)) (expression float floor (swiz w (var_ref x)))))
- (return (var_ref t))))
-))
-
+++ /dev/null
-((function greaterThan
- (signature bvec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function greaterThanEqual
- (signature bvec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function inversesqrt
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float rsq (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 rsq (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 rsq (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 rsq (var_ref arg0)))))
-))
+++ /dev/null
-((function length
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
-
- (signature float
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
-
- (signature float
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
-
- (signature float
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
-))
+++ /dev/null
-((function lessThan
- (signature bvec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function lessThanEqual
- (signature bvec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function log
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float log (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 log (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 log (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 log (var_ref arg0)))))
-))
+++ /dev/null
-((function log2
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float log2 (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 log2 (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 log2 (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 log2 (var_ref arg0)))))
-))
+++ /dev/null
-((function matrixCompMult
- (signature mat2
- (parameters
- (declare (in) mat2 x)
- (declare (in) mat2 y))
- ((declare () mat2 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
-(return (var_ref z))))
-
- (signature mat3
- (parameters
- (declare (in) mat3 x)
- (declare (in) mat3 y))
- ((declare () mat3 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
-(return (var_ref z))))
-
- (signature mat4
- (parameters
- (declare (in) mat4 x)
- (declare (in) mat4 y))
- ((declare () mat4 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec4 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3)))))
-(return (var_ref z))))
-))
-
+++ /dev/null
-((function max
- (signature float
- (parameters
- (declare (in) float arg0)
- (declare (in) float arg1))
- ((return (expression float max (var_ref arg0) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((return (expression vec2 max (var_ref arg0) (var_ref arg1)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((return (expression vec3 max (var_ref arg0) (var_ref arg1)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((return (expression vec4 max (var_ref arg0) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) float arg1))
- ((declare () vec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) float arg1))
- ((declare () vec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) float arg1))
- ((declare () vec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result))
- (expression float max (swiz w (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-))
+++ /dev/null
-((function min
- (signature float
- (parameters
- (declare (in) float arg0)
- (declare (in) float arg1))
- ((return (expression float min (var_ref arg0) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((return (expression vec2 min (var_ref arg0) (var_ref arg1)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((return (expression vec3 min (var_ref arg0) (var_ref arg1)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((return (expression vec4 min (var_ref arg0) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) float arg1))
- ((declare () vec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) float arg1))
- ((declare () vec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) float arg1))
- ((declare () vec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result))
- (expression float min (swiz w (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-))
+++ /dev/null
-((function mix
- (signature float
- (parameters
- (declare (in) float arg0)
- (declare (in) float arg1)
- (declare (in) float arg2))
- ((return (expression float + (expression float * (var_ref arg0) (expression float - (constant float (1.000000)) (var_ref arg2))) (expression float * (var_ref arg1) (var_ref arg2))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1)
- (declare (in) vec2 arg2))
- ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1)
- (declare (in) vec3 arg2))
- ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1)
- (declare (in) vec4 arg2))
- ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1)
- (declare (in) float arg2))
- ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1)
- (declare (in) float arg2))
- ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1)
- (declare (in) float arg2))
- ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))
-))
+++ /dev/null
-((function mod
- (signature float
- (parameters
- (declare (in) float arg0)
- (declare (in) float arg1))
- ((return (expression float % (var_ref arg0) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((return (expression vec2 % (var_ref arg0) (var_ref arg1)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((return (expression vec3 % (var_ref arg0) (var_ref arg1)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((return (expression vec4 % (var_ref arg0) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) float arg1))
- ((declare () vec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) float arg1))
- ((declare () vec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) float arg1))
- ((declare () vec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result))
- (expression float % (swiz w (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-))
+++ /dev/null
-((function noise1
- (signature float
- (parameters
- (declare (in) float x))
- ((return (constant float (0)))))
- (signature float
- (parameters
- (declare (in) vec2 x))
- ((return (constant float (0)))))
- (signature float
- (parameters
- (declare (in) vec3 x))
- ((return (constant float (0)))))
- (signature float
- (parameters
- (declare (in) vec4 x))
- ((return (constant float (0)))))
- )
-
- (function noise2
- (signature vec2
- (parameters
- (declare (in) float x))
- ((return (constant vec2 (0 0)))))
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((return (constant vec2 (0 0)))))
- (signature vec2
- (parameters
- (declare (in) vec3 x))
- ((return (constant vec2 (0 0)))))
- (signature vec2
- (parameters
- (declare (in) vec4 x))
- ((return (constant vec2 (0 0)))))
- )
-
- (function noise3
- (signature vec3
- (parameters
- (declare (in) float x))
- ((return (constant vec3 (0 0 0)))))
- (signature vec3
- (parameters
- (declare (in) vec2 x))
- ((return (constant vec3 (0 0 0)))))
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((return (constant vec3 (0 0 0)))))
- (signature vec3
- (parameters
- (declare (in) vec4 x))
- ((return (constant vec3 (0 0 0)))))
- )
-
- (function noise4
- (signature vec4
- (parameters
- (declare (in) float x))
- ((return (constant vec4 (0 0 0 0)))))
- (signature vec4
- (parameters
- (declare (in) vec2 x))
- ((return (constant vec4 (0 0 0 0)))))
- (signature vec4
- (parameters
- (declare (in) vec3 x))
- ((return (constant vec4 (0 0 0 0)))))
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((return (constant vec4 (0 0 0 0)))))
- )
-)
+++ /dev/null
-((function normalize
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
-))
+++ /dev/null
-((function not
- (signature bvec2
- (parameters
- (declare (in) bvec2 arg0))
- ((return (expression bvec2 ! (var_ref arg0)))))
-
- (signature bvec3
- (parameters
- (declare (in) bvec3 arg0))
- ((return (expression bvec3 ! (var_ref arg0)))))
-
- (signature bvec4
- (parameters
- (declare (in) bvec4 arg0))
- ((return (expression bvec4 ! (var_ref arg0)))))
-))
+++ /dev/null
-((function notEqual
- (signature bvec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression float != (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression int != (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function pow
- (signature float
- (parameters
- (declare (in) float arg0)
- (declare (in) float arg1))
- ((return (expression float pow (var_ref arg0) (var_ref arg1)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0)
- (declare (in) vec2 arg1))
- ((return (expression vec2 pow (var_ref arg0) (var_ref arg1)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0)
- (declare (in) vec3 arg1))
- ((return (expression vec3 pow (var_ref arg0) (var_ref arg1)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0)
- (declare (in) vec4 arg1))
- ((return (expression vec4 pow (var_ref arg0) (var_ref arg1)))))
-))
+++ /dev/null
-((function radians
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float * (var_ref arg0) (constant float (0.017453))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 * (var_ref arg0) (constant float (0.017453))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 * (var_ref arg0) (constant float (0.017453))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 * (var_ref arg0) (constant float (0.017453))))))
-))
+++ /dev/null
-((function reflect
- (signature float
- (parameters
- (declare (in) float i)
- (declare (in) float n))
- ((return (expression float -
- (var_ref i)
- (expression float *
- (constant float (2.0))
- (expression float *
- (expression float dot
- (var_ref n)
- (var_ref i))
- (var_ref n)))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 i)
- (declare (in) vec2 n))
- ((return (expression vec2 -
- (var_ref i)
- (expression vec2 *
- (constant float (2.0))
- (expression vec2 *
- (expression float dot
- (var_ref n)
- (var_ref i))
- (var_ref n)))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 i)
- (declare (in) vec3 n))
- ((return (expression vec3 -
- (var_ref i)
- (expression vec3 *
- (constant float (2.0))
- (expression vec3 *
- (expression float dot
- (var_ref n)
- (var_ref i))
- (var_ref n)))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 i)
- (declare (in) vec4 n))
- ((return (expression vec4 -
- (var_ref i)
- (expression vec4 *
- (constant float (2.0))
- (expression vec4 *
- (expression float dot
- (var_ref n)
- (var_ref i))
- (var_ref n)))))))
-
-))
+++ /dev/null
-((function refract
- (signature float
- (parameters
- (declare (in) float i)
- (declare (in) float n)
- (declare (in) float eta))
- ((declare () float k)
- (assign (constant bool (1)) (var_ref k)
- (expression float - (constant float (1.0))
- (expression float * (var_ref eta)
- (expression float * (var_ref eta)
- (expression float - (constant float (1.0))
- (expression float *
- (expression float dot (var_ref n) (var_ref i))
- (expression float dot (var_ref n) (var_ref i))))))))
- (if (expression bool < (var_ref k) (constant float (0.0)))
- ((return (constant float (0.0))))
- ((return (expression float -
- (expression float * (var_ref eta) (var_ref i))
- (expression float *
- (expression float +
- (expression float * (var_ref eta)
- (expression float dot (var_ref n) (var_ref i)))
- (expression float sqrt (var_ref k)))
- (var_ref n))))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 i)
- (declare (in) vec2 n)
- (declare (in) float eta))
- ((declare () float k)
- (assign (constant bool (1)) (var_ref k)
- (expression float - (constant float (1.0))
- (expression float * (var_ref eta)
- (expression float * (var_ref eta)
- (expression float - (constant float (1.0))
- (expression float *
- (expression float dot (var_ref n) (var_ref i))
- (expression float dot (var_ref n) (var_ref i))))))))
- (if (expression bool < (var_ref k) (constant float (0.0)))
- ((return (constant vec2 (0.0 0.0))))
- ((return (expression vec2 -
- (expression vec2 * (var_ref eta) (var_ref i))
- (expression vec2 *
- (expression float +
- (expression float * (var_ref eta)
- (expression float dot (var_ref n) (var_ref i)))
- (expression float sqrt (var_ref k)))
- (var_ref n))))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 i)
- (declare (in) vec3 n)
- (declare (in) float eta))
- ((declare () float k)
- (assign (constant bool (1)) (var_ref k)
- (expression float - (constant float (1.0))
- (expression float * (var_ref eta)
- (expression float * (var_ref eta)
- (expression float - (constant float (1.0))
- (expression float *
- (expression float dot (var_ref n) (var_ref i))
- (expression float dot (var_ref n) (var_ref i))))))))
- (if (expression bool < (var_ref k) (constant float (0.0)))
- ((return (constant vec3 (0.0 0.0))))
- ((return (expression vec3 -
- (expression vec3 * (var_ref eta) (var_ref i))
- (expression vec3 *
- (expression float +
- (expression float * (var_ref eta)
- (expression float dot (var_ref n) (var_ref i)))
- (expression float sqrt (var_ref k)))
- (var_ref n))))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 i)
- (declare (in) vec4 n)
- (declare (in) float eta))
- ((declare () float k)
- (assign (constant bool (1)) (var_ref k)
- (expression float - (constant float (1.0))
- (expression float * (var_ref eta)
- (expression float * (var_ref eta)
- (expression float - (constant float (1.0))
- (expression float *
- (expression float dot (var_ref n) (var_ref i))
- (expression float dot (var_ref n) (var_ref i))))))))
- (if (expression bool < (var_ref k) (constant float (0.0)))
- ((return (constant vec4 (0.0 0.0))))
- ((return (expression vec4 -
- (expression vec4 * (var_ref eta) (var_ref i))
- (expression vec4 *
- (expression float +
- (expression float * (var_ref eta)
- (expression float dot (var_ref n) (var_ref i)))
- (expression float sqrt (var_ref k)))
- (var_ref n))))))))
-
-))
+++ /dev/null
-((function sign
- (signature float
- (parameters
- (declare (in) float x))
- ((return (expression float sign (var_ref x)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((declare () vec2 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))
- (return (var_ref t))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((declare () vec3 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))
- (return (var_ref t))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((declare () vec4 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))
- (assign (constant bool (1)) (swiz w (var_ref t)) (expression float sign (swiz w (var_ref x))))
- (return (var_ref t))))
-))
-
+++ /dev/null
-((function sin
- (signature float
- (parameters
- (declare (in) float angle))
- ((return (expression float sin (var_ref angle)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 angle))
- ((return (expression vec2 sin (var_ref angle)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 angle))
- ((return (expression vec3 sin (var_ref angle)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 angle))
- ((return (expression vec4 sin (var_ref angle)))))
-))
+++ /dev/null
-((function smoothstep
- (signature float
- (parameters
- (declare (in) float edge0)
- (declare (in) float edge1)
- (declare (in) float x))
- ((declare () float t)
-
- (assign (constant bool (1)) (var_ref t)
- (expression float max
- (expression float min
- (expression float / (expression float - (var_ref x) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (return (expression float * (var_ref t) (expression float * (var_ref t) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (var_ref t))))))))
-
- (signature vec2
- (parameters
- (declare (in) float edge0)
- (declare (in) float edge1)
- (declare (in) vec2 x))
- ((declare () vec2 t)
- (declare () vec2 retval)
-
- (assign (constant bool (1)) (swiz x (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz y (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
- (return (var_ref retval))
- ))
-
- (signature vec3
- (parameters
- (declare (in) float edge0)
- (declare (in) float edge1)
- (declare (in) vec3 x))
- ((declare () vec3 t)
- (declare () vec3 retval)
-
- (assign (constant bool (1)) (swiz x (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz y (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz z (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
- (return (var_ref retval))
- ))
-
-
- (signature vec4
- (parameters
- (declare (in) float edge0)
- (declare (in) float edge1)
- (declare (in) vec4 x))
- ((declare () vec4 t)
- (declare () vec4 retval)
-
- (assign (constant bool (1)) (swiz x (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz y (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz z (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz w (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz w (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))
- (return (var_ref retval))
- ))
-
- (signature vec2
- (parameters
- (declare (in) vec2 edge0)
- (declare (in) vec2 edge1)
- (declare (in) vec2 x))
- ((declare () vec2 t)
- (declare () vec2 retval)
-
- (assign (constant bool (1)) (swiz x (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz y (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
- (return (var_ref retval))
- ))
-
- (signature vec3
- (parameters
- (declare (in) vec3 edge0)
- (declare (in) vec3 edge1)
- (declare (in) vec3 x))
- ((declare () vec3 t)
- (declare () vec3 retval)
-
- (assign (constant bool (1)) (swiz x (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz y (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz z (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
- (return (var_ref retval))
- ))
-
-
- (signature vec4
- (parameters
- (declare (in) vec4 edge0)
- (declare (in) vec4 edge1)
- (declare (in) vec4 x))
- ((declare () vec4 t)
- (declare () vec4 retval)
-
- (assign (constant bool (1)) (swiz x (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz y (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz z (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
-
- (assign (constant bool (1)) (swiz w (var_ref t))
- (expression float max
- (expression float min
- (expression float / (expression float - (swiz w (var_ref x)) (swiz w (var_ref edge0))) (expression float - (swiz w (var_ref edge1)) (swiz w (var_ref edge0))))
- (constant float (1.0)))
- (constant float (0.0))))
- (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))
- (return (var_ref retval))
- ))
-
-))
-
+++ /dev/null
-((function sqrt
- (signature float
- (parameters
- (declare (in) float arg0))
- ((return (expression float sqrt (var_ref arg0)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 arg0))
- ((return (expression vec2 sqrt (var_ref arg0)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 arg0))
- ((return (expression vec3 sqrt (var_ref arg0)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 arg0))
- ((return (expression vec4 sqrt (var_ref arg0)))))
-))
+++ /dev/null
-((function step
- (signature float
- (parameters
- (declare (in) float edge)
- (declare (in) float x))
- ((return (expression float b2f (expression bool < (var_ref x) (var_ref edge))))))
-
- (signature vec2
- (parameters
- (declare (in) float edge)
- (declare (in) vec2 x))
- ((declare () vec2 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))
- (return (var_ref t))))
-
- (signature vec3
- (parameters
- (declare (in) float edge)
- (declare (in) vec3 x))
- ((declare () vec3 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))
- (return (var_ref t))))
-
- (signature vec4
- (parameters
- (declare (in) float edge)
- (declare (in) vec4 x))
- ((declare () vec4 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))
- (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(var_ref edge))))
- (return (var_ref t))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 edge)
- (declare (in) vec2 x))
- ((declare () vec2 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))
- (return (var_ref t))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 edge)
- (declare (in) vec3 x))
- ((declare () vec3 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(swiz z (var_ref edge)))))
- (return (var_ref t))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 edge)
- (declare (in) vec4 x))
- ((declare () vec4 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz z (var_ref edge)))))
- (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(swiz w (var_ref edge)))))
- (return (var_ref t))))
-))
-
+++ /dev/null
-((function tan
- (signature float
- (parameters
- (declare (in) float angle))
- ((return (expression float / (expression float sin (var_ref angle)) (expression float cos (var_ref angle))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 angle))
- ((return (expression float / (expression float sin (var_ref angle)) (expression vec2 cos (var_ref angle))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 angle))
- ((return (expression float / (expression float sin (var_ref angle)) (expression vec3 cos (var_ref angle))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 angle))
- ((return (expression float / (expression float sin (var_ref angle)) (expression vec4 cos (var_ref angle))))))
-))
+++ /dev/null
-((function texture1D
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) float P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-)
- (function texture1DLod
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) float P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
-)
- (function texture1DProj
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
-)
- (function texture1DProjLod
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
-)
- (function texture2D
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-)
-(function texture2DLod
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
-)
- (function texture2DProj
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
-)
- (function texture2DProjLod
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
-)
- (function texture3D
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-)
- (function texture3DLod
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
-)
- (function texture3DProj
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
-)
- (function texture3DProjLod
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
-)
- (function textureCube
- (signature vec4
- (parameters
- (declare (in) samplerCube sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-)
- (function textureCubeLod
- (signature vec4
- (parameters
- (declare (in) samplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
-)
- (function shadow1D
- (signature vec4
- (parameters
- (declare (in) sampler1DShadow sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
-
-)
- (function shadow1DLod
- (signature vec4
- (parameters
- (declare (in) sampler1DShadow sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))
-
-)
- (function shadow1DProj
- (signature vec4
- (parameters
- (declare (in) sampler1DShadow sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))
-
-)
- (function shadow1DProjLod
- (signature vec4
- (parameters
- (declare (in) sampler1DShadow sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))
-
-)
- (function shadow2D
- (signature vec4
- (parameters
- (declare (in) sampler2DShadow sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
-
-)
- (function shadow2DLod
- (signature vec4
- (parameters
- (declare (in) sampler2DShadow sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))
-
-)
- (function shadow2DProj
- (signature vec4
- (parameters
- (declare (in) sampler2DShadow sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))
-
-)
- (function shadow2DProjLod
- (signature vec4
- (parameters
- (declare (in) sampler2DShadow sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))
-
-))
+++ /dev/null
-((function dFdx
- (signature float
- (parameters
- (declare (in) float p))
- ((return (expression float dFdx (var_ref p)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 p))
- ((return (expression vec2 dFdx (var_ref p)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 p))
- ((return (expression vec3 dFdx (var_ref p)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 p))
- ((return (expression vec4 dFdx (var_ref p)))))
- )
-
- (function dFdy
- (signature float
- (parameters
- (declare (in) float p))
- ((return (expression float dFdy (var_ref p)))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 p))
- ((return (expression vec2 dFdy (var_ref p)))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 p))
- ((return (expression vec3 dFdy (var_ref p)))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 p))
- ((return (expression vec4 dFdy (var_ref p)))))
- )
-
- (function fwidth
- (signature float
- (parameters
- (declare (in) float p))
- ((return (expression float +
- (expression float abs (expression float dFdx (var_ref p)))
- (expression float abs (expression float dFdy (var_ref p)))))))
-
- (signature vec2
- (parameters
- (declare (in) vec2 p))
- ((return (expression vec2 +
- (expression vec2 abs (expression vec2 dFdx (var_ref p)))
- (expression vec2 abs (expression vec2 dFdy (var_ref p)))))))
-
- (signature vec3
- (parameters
- (declare (in) vec3 p))
- ((return (expression vec3 +
- (expression vec3 abs (expression vec3 dFdx (var_ref p)))
- (expression vec3 abs (expression vec3 dFdy (var_ref p)))))))
-
- (signature vec4
- (parameters
- (declare (in) vec4 p))
- ((return (expression vec4 +
- (expression vec4 abs (expression vec4 dFdx (var_ref p)))
- (expression vec4 abs (expression vec4 dFdy (var_ref p)))))))
-))
+++ /dev/null
-((function texture1D
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) float P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
-)
- (function texture1DProj
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
-)
- (function texture2D
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
-)
- (function texture2DProj
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
-)
- (function texture3D
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
-)
- (function texture3DProj
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
-)
- (function textureCube
- (signature vec4
- (parameters
- (declare (in) samplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
-)
- (function shadow1D
- (signature vec4
- (parameters
- (declare (in) sampler1DShadow sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))
-
-)
- (function shadow1DProj
- (signature vec4
- (parameters
- (declare (in) sampler1DShadow sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))
-
-)
- (function shadow2D
- (signature vec4
- (parameters
- (declare (in) sampler2DShadow sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))
-
-)
- (function shadow2DProj
- (signature vec4
- (parameters
- (declare (in) sampler2DShadow sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))
-
-))
+++ /dev/null
-((function ftransform
- (signature vec4
- (parameters)
- ((return (expression vec4 *
- (var_ref gl_ModelViewProjectionMatrix)
- (var_ref gl_Vertex)))))
-))
+++ /dev/null
-((function matrixCompMult
- (signature mat2x3
- (parameters
- (declare (in) mat2x3 x)
- (declare (in) mat2x3 y))
- ((declare () mat2x3 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
-(return (var_ref z))))
-
- (signature mat3x2
- (parameters
- (declare (in) mat3x2 x)
- (declare (in) mat3x2 y))
- ((declare () mat3x2 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
-(return (var_ref z))))
-
- (signature mat2x4
- (parameters
- (declare (in) mat2x4 x)
- (declare (in) mat2x4 y))
- ((declare () mat2x4 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
-(return (var_ref z))))
-
- (signature mat4x2
- (parameters
- (declare (in) mat4x2 x)
- (declare (in) mat4x2 y))
- ((declare () mat4x2 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec2 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3)))))
-(return (var_ref z))))
-
- (signature mat3x4
- (parameters
- (declare (in) mat3x4 x)
- (declare (in) mat3x4 y))
- ((declare () mat3x4 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
-(return (var_ref z))))
-
- (signature mat4x3
- (parameters
- (declare (in) mat4x3 x)
- (declare (in) mat4x3 y))
- ((declare () mat4x3 z)
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
- (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec3 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3)))))
-(return (var_ref z))))
-))
+++ /dev/null
-((function outerProduct
- (signature mat2
- (parameters
- (declare (in) vec2 u)
- (declare (in) vec2 v))
- ((declare () mat2 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u))))
-(return (var_ref m))))
-
- (signature mat2x3
- (parameters
- (declare (in) vec2 u)
- (declare (in) vec3 v))
- ((declare () mat2x3 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u))))
-(return (var_ref m))))
-
- (signature mat2x4
- (parameters
- (declare (in) vec2 u)
- (declare (in) vec4 v))
- ((declare () mat2x4 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u))))
-(return (var_ref m))))
-
- (signature mat3x2
- (parameters
- (declare (in) vec3 u)
- (declare (in) vec2 v))
- ((declare () mat3x2 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u))))
-(return (var_ref m))))
-
- (signature mat3
- (parameters
- (declare (in) vec3 u)
- (declare (in) vec3 v))
- ((declare () mat3 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u))))
-(return (var_ref m))))
-
- (signature mat3x4
- (parameters
- (declare (in) vec3 u)
- (declare (in) vec4 v))
- ((declare () mat3x4 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u))))
-(return (var_ref m))))
-
- (signature mat4x2
- (parameters
- (declare (in) vec4 u)
- (declare (in) vec2 v))
- ((declare () mat4x2 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec2 * (var_ref v) (swiz w (var_ref u))))
-(return (var_ref m))))
-
- (signature mat4x3
- (parameters
- (declare (in) vec4 u)
- (declare (in) vec3 v))
- ((declare () mat4x3 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec3 * (var_ref v) (swiz w (var_ref u))))
-(return (var_ref m))))
-
- (signature mat4
- (parameters
- (declare (in) vec4 u)
- (declare (in) vec4 v))
- ((declare () mat4 m)
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u))))
- (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec4 * (var_ref v) (swiz w (var_ref u))))
-(return (var_ref m))))
-))
-
+++ /dev/null
-((function transpose
- (signature mat2
- (parameters
- (declare (in) mat2 m))
- ((declare () mat2 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
-(return (var_ref t))))
-
- (signature mat3x2
- (parameters
- (declare (in) mat2x3 m))
- ((declare () mat3x2 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
-(return (var_ref t))))
-
- (signature mat4x2
- (parameters
- (declare (in) mat2x4 m))
- ((declare () mat4x2 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1)))))
-(return (var_ref t))))
-
- (signature mat2x3
- (parameters
- (declare (in) mat3x2 m))
- ((declare () mat2x3 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
-(return (var_ref t))))
-
- (signature mat3
- (parameters
- (declare (in) mat3 m))
- ((declare () mat3 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
-(return (var_ref t))))
-
- (signature mat4x3
- (parameters
- (declare (in) mat3x4 m))
- ((declare () mat4x3 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2)))))
-(return (var_ref t))))
-
- (signature mat2x4
- (parameters
- (declare (in) mat4x2 m))
- ((declare () mat2x4 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3)))))
-(return (var_ref t))))
-
- (signature mat3x4
- (parameters
- (declare (in) mat4x3 m))
- ((declare () mat3x4 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3)))))
-(return (var_ref t))))
-
- (signature mat4
- (parameters
- (declare (in) mat4 m))
- ((declare () mat4 t)
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3)))))
- (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (3)))))
-(return (var_ref t))))
-)
-
-)
-
+++ /dev/null
-((function clamp
- (signature int
- (parameters
- (declare (in) int arg0)
- (declare (in) int arg1)
- (declare (in) int arg2))
- ((return (expression int max (expression int min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature ivec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1)
- (declare (in) ivec2 arg2))
- ((return (expression ivec2 max (expression ivec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature ivec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1)
- (declare (in) ivec3 arg2))
- ((return (expression ivec3 max (expression ivec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature ivec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1)
- (declare (in) ivec4 arg2))
- ((return (expression ivec4 max (expression ivec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature ivec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) int arg1)
- (declare (in) int arg2))
- ((declare () ivec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature ivec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) int arg1)
- (declare (in) int arg2))
- ((declare () ivec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature ivec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) int arg1)
- (declare (in) int arg2))
- ((declare () ivec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uint
- (parameters
- (declare (in) uint arg0)
- (declare (in) uint arg1)
- (declare (in) uint arg2))
- ((return (expression uint max (expression uint min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature uvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1)
- (declare (in) uvec2 arg2))
- ((return (expression uvec2 max (expression uvec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature uvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1)
- (declare (in) uvec3 arg2))
- ((return (expression uvec3 max (expression uvec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature uvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1)
- (declare (in) uvec4 arg2))
- ((return (expression uvec4 max (expression uvec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
-
- (signature uvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uint arg1)
- (declare (in) uint arg2))
- ((declare () uvec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uint arg1)
- (declare (in) uint arg2))
- ((declare () uvec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uint arg1)
- (declare (in) uint arg2))
- ((declare () uvec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
- (return (var_ref result))))
-))
+++ /dev/null
-((function cosh
- (signature float
- (parameters
- (declare (in) float x))
- ((return (expression float * (constant float (0.5))
- (expression float +
- (expression float exp (var_ref x))
- (expression float exp (expression float neg (var_ref x))))))))
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((return (expression vec2 * (constant vec2 (0.5))
- (expression vec2 +
- (expression vec2 exp (var_ref x))
- (expression vec2 exp (expression vec2 neg (var_ref x))))))))
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((return (expression vec3 * (constant vec3 (0.5))
- (expression vec3 +
- (expression vec3 exp (var_ref x))
- (expression vec3 exp (expression vec3 neg (var_ref x))))))))
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((return (expression vec4 * (constant vec4 (0.5))
- (expression vec4 +
- (expression vec4 exp (var_ref x))
- (expression vec4 exp (expression vec4 neg (var_ref x))))))))
-))
+++ /dev/null
-((function equal
- (signature bvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function greaterThan
- (signature bvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function greaterThanEqual
- (signature bvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function lessThan
- (signature bvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function lessThanEqual
- (signature bvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function max
- (signature int
- (parameters
- (declare (in) int arg0)
- (declare (in) int arg1))
- ((return (expression int max (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((return (expression ivec2 max (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((return (expression ivec3 max (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((return (expression ivec4 max (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) int arg1))
- ((declare () ivec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature ivec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) int arg1))
- ((declare () ivec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature ivec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) int arg1))
- ((declare () ivec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result))
- (expression int max (swiz w (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uint
- (parameters
- (declare (in) uint arg0)
- (declare (in) uint arg1))
- ((return (expression uint max (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((return (expression uvec2 max (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((return (expression uvec3 max (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((return (expression uvec4 max (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uint arg1))
- ((declare () uvec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uint arg1))
- ((declare () uvec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uint arg1))
- ((declare () uvec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result))
- (expression uint max (swiz w (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-))
+++ /dev/null
-((function min
- (signature int
- (parameters
- (declare (in) int arg0)
- (declare (in) int arg1))
- ((return (expression int min (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) ivec2 arg1))
- ((return (expression ivec2 min (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) ivec3 arg1))
- ((return (expression ivec3 min (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) ivec4 arg1))
- ((return (expression ivec4 min (var_ref arg0) (var_ref arg1)))))
-
- (signature ivec2
- (parameters
- (declare (in) ivec2 arg0)
- (declare (in) int arg1))
- ((declare () ivec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature ivec3
- (parameters
- (declare (in) ivec3 arg0)
- (declare (in) int arg1))
- ((declare () ivec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature ivec4
- (parameters
- (declare (in) ivec4 arg0)
- (declare (in) int arg1))
- ((declare () ivec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result))
- (expression int min (swiz w (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uint
- (parameters
- (declare (in) uint arg0)
- (declare (in) uint arg1))
- ((return (expression uint min (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((return (expression uvec2 min (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((return (expression uvec3 min (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((return (expression uvec4 min (var_ref arg0) (var_ref arg1)))))
-
- (signature uvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uint arg1))
- ((declare () uvec2 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uint arg1))
- ((declare () uvec3 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-
- (signature uvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uint arg1))
- ((declare () uvec4 result)
- (assign (constant bool (1)) (swiz x (var_ref result))
- (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz y (var_ref result))
- (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz z (var_ref result))
- (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))
- (assign (constant bool (1)) (swiz w (var_ref result))
- (expression uint min (swiz w (var_ref arg0)) (var_ref arg1)))
- (return (var_ref result))))
-))
+++ /dev/null
-((function notEqual
- (signature bvec2
- (parameters
- (declare (in) uvec2 arg0)
- (declare (in) uvec2 arg1))
- ((declare () bvec2 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec3
- (parameters
- (declare (in) uvec3 arg0)
- (declare (in) uvec3 arg1))
- ((declare () bvec3 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (return (var_ref temp))))
-
- (signature bvec4
- (parameters
- (declare (in) uvec4 arg0)
- (declare (in) uvec4 arg1))
- ((declare () bvec4 temp)
- (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
- (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
- (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
- (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool != (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
- (return (var_ref temp))))
-))
+++ /dev/null
-((function sign
- (signature int
- (parameters
- (declare (in) int x))
- ((return (expression int / (var_ref x) (expression int abs (var_ref x))))))
-
- (signature ivec2
- (parameters
- (declare (in) ivec2 x))
- ((declare () ivec2 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))
- (return (var_ref t))))
-
- (signature ivec3
- (parameters
- (declare (in) ivec3 x))
- ((declare () ivec3 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))
- (return (var_ref t))))
-
- (signature ivec4
- (parameters
- (declare (in) ivec4 x))
- ((declare () ivec4 t)
- (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))
- (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))
- (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))
- (assign (constant bool (1)) (swiz w (var_ref t)) (expression int sign (swiz w (var_ref x))))
- (return (var_ref t))))
-))
-
+++ /dev/null
-((function sinh
- (signature float
- (parameters
- (declare (in) float x))
- ((return (expression float * (constant float (0.5))
- (expression float -
- (expression float exp (var_ref x))
- (expression float exp (expression float neg (var_ref x))))))))
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((return (expression vec2 * (constant vec2 (0.5))
- (expression vec2 -
- (expression vec2 exp (var_ref x))
- (expression vec2 exp (expression vec2 neg (var_ref x))))))))
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((return (expression vec3 * (constant vec3 (0.5))
- (expression vec3 -
- (expression vec3 exp (var_ref x))
- (expression vec3 exp (expression vec3 neg (var_ref x))))))))
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((return (expression vec4 * (constant vec4 (0.5))
- (expression vec4 -
- (expression vec4 exp (var_ref x))
- (expression vec4 exp (expression vec4 neg (var_ref x))))))))
-))
+++ /dev/null
-((function tanh
- (signature float
- (parameters
- (declare (in) float x))
- ((return (expression float /
- (expression float -
- (expression float exp (var_ref x))
- (expression float exp (expression float neg (var_ref x))))
- (expression float +
- (expression float exp (var_ref x))
- (expression float exp (expression float neg (var_ref x))))))))
- (signature vec2
- (parameters
- (declare (in) vec2 x))
- ((return (expression vec2 /
- (expression vec2 -
- (expression vec2 exp (var_ref x))
- (expression vec2 exp (expression vec2 neg (var_ref x))))
- (expression vec2 +
- (expression vec2 exp (var_ref x))
- (expression vec2 exp (expression vec2 neg (var_ref x))))))))
- (signature vec3
- (parameters
- (declare (in) vec3 x))
- ((return (expression vec3 /
- (expression vec3 -
- (expression vec3 exp (var_ref x))
- (expression vec3 exp (expression vec3 neg (var_ref x))))
- (expression vec3 +
- (expression vec3 exp (var_ref x))
- (expression vec3 exp (expression vec3 neg (var_ref x))))))))
- (signature vec4
- (parameters
- (declare (in) vec4 x))
- ((return (expression vec4 /
- (expression vec4 -
- (expression vec4 exp (var_ref x))
- (expression vec4 exp (expression vec4 neg (var_ref x))))
- (expression vec4 +
- (expression vec4 exp (var_ref x))
- (expression vec4 exp (expression vec4 neg (var_ref x))))))))
-))
+++ /dev/null
-((function texelFetch
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) int P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) int P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) int P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) ivec2 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) ivec2 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) ivec2 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) ivec3 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) ivec3 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) ivec3 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) ivec2 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1DArray sampler)
- (declare (in) ivec2 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1DArray sampler)
- (declare (in) ivec2 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) ivec3 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2DArray sampler)
- (declare (in) ivec3 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2DArray sampler)
- (declare (in) ivec3 P)
- (declare (in) int lod) )
- ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
-
-))
+++ /dev/null
-((function texture
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) float P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) float P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) float P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature vec4
- (parameters
- (declare (in) samplerCube sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isamplerCube sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usamplerCube sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1DArray sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1DArray sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2DArray sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2DArray sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-))
+++ /dev/null
-((function textureGrad
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) float P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) float P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) float P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) samplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isamplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usamplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
-
-)
-)
+++ /dev/null
-((function textureLod
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) float P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) float P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) float P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) samplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isamplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usamplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
-))
+++ /dev/null
-((function textureProj
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
-
-))
+++ /dev/null
-((function textureLod
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float dPdx)
- (declare (in) float dPdy) )
- ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) vec2 dPdx)
- (declare (in) vec2 dPdy) )
- ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) vec3 dPdx)
- (declare (in) vec3 dPdy) )
- ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
-
-))
+++ /dev/null
-((function textureLod
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
-
-))
+++ /dev/null
-((function texture
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) float P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) float P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) float P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) samplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isamplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usamplerCube sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
-))
+++ /dev/null
-((function textureProj
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler1D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler2D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature vec4
- (parameters
- (declare (in) sampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature ivec4
- (parameters
- (declare (in) isampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
- (signature uvec4
- (parameters
- (declare (in) usampler3D sampler)
- (declare (in) vec4 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
-
-))
+++ /dev/null
-((function texture2DRect
- (signature vec4
- (parameters
- (declare (in) sampler2DRect sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-)
- (function shadow2DRect
- (signature vec4
- (parameters
- (declare (in) sampler2DRectShadow sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
-
-))
+++ /dev/null
-((function texture1DArray
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) vec2 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-)
- (function texture1DArrayLod
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
-)
- (function texture2DArray
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
-
-)
- (function texture2DArrayLod
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
-
-)
- (function shadow1DArray
- (signature vec4
- (parameters
- (declare (in) sampler1DArrayShadow sampler)
- (declare (in) vec3 P) )
- ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
-
-)
- (function shadow1DArrayLod
- (signature vec4
- (parameters
- (declare (in) sampler1DArrayShadow sampler)
- (declare (in) vec3 P)
- (declare (in) float lod) )
- ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))
-
-)
- (function shadow2DArray
- (signature vec4
- (parameters
- (declare (in) sampler2DArrayShadow sampler)
- (declare (in) vec4 P) )
- ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) 1 (swiz w (var_ref P)) ))))
-
-))
+++ /dev/null
-((function texture1DArray
- (signature vec4
- (parameters
- (declare (in) sampler1DArray sampler)
- (declare (in) vec2 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
-)
- (function texture2DArray
- (signature vec4
- (parameters
- (declare (in) sampler2DArray sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
-
-)
- (function shadow1DArray
- (signature vec4
- (parameters
- (declare (in) sampler1DArrayShadow sampler)
- (declare (in) vec3 P)
- (declare (in) float bias) )
- ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))
-
-))
+++ /dev/null
-#!/usr/bin/env perl
-
-sub process_version {
- my ($version) = @_;
- my @vars;
- print "/* $version builtins */\n\n";
-
- my @files = <builtins/$version/*>;
- foreach $file (@files) {
- push(@vars, process_file($file));
- }
-
- print "static const char *functions_for_$version [] = {\n";
- foreach $var (@vars) {
- print " $var,\n";
- }
- print "};\n\n"
-}
-
-sub process_file {
- my ($file) = @_;
-
- # Change from builtins/110/foo to builtins_110_foo
- my $var = $file; $var =~ s!/!_!g;
-
- print "static const char *$var = {\n";
- open SRC, "<", "$file" or die $!;
- while (<SRC>) {
- s/\\/\\\\/g;
- s/\"/\\\"/g;
- s/\n/\\n/g;
- print " \"$_\"\n";
- }
- print "};\n\n";
- close SRC or die $!;
- return $var;
-}
-
-print << 'EOF';
-/* DO NOT MODIFY - automatically generated by generate_builtins.pl */
-/*
- * 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 <stdio.h>
-#include "glsl_parser_extras.h"
-#include "ir_reader.h"
-
-void
-read_builtins(_mesa_glsl_parse_state *st, exec_list *instructions,
- const char **functions, unsigned count)
-{
- if (st->error)
- return;
-
- for (unsigned i = 0; i < count; i++) {
- _mesa_glsl_read_ir(st, instructions, functions[i]);
-
- if (st->error) {
- printf("error reading builtin: %.35s ...\n", functions[i]);
- return;
- }
- }
-}
-
-EOF
-
-@versions = sort(<builtins/[1-9A-Z]*>);
-foreach $version (@versions) {
- $version =~ s!builtins/!!g;
- process_version($version);
-}
-
-print << 'EOF';
-void
-_mesa_glsl_initialize_functions(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
-EOF
-
-foreach $version_xs (@versions) {
- $check = "";
- if ($version_xs =~ /_vs/) {
- $check = "state->target == vertex_shader && ";
- } elsif ($version_xs =~ /_fs/) {
- $check = "state->target == fragment_shader && ";
- }
- $version = $version_xs;
- $version =~ s/_[vf]s//g;
-
- if ($version =~ /^[1-9][0-9][0-9]/) {
- $check = "${check}state->language_version >= $version";
- } else {
- # Not a version...an extension name
- $check = "${check}state->${version}_enable";
- }
- print " if ($check)\n";
- print " read_builtins(state, instructions,\n";
- print " functions_for_$version_xs,\n";
- print " sizeof(functions_for_$version_xs) / ";
- print "sizeof(const char *));\n\n"
-}
-
-print "}\n";
+++ /dev/null
-#!/usr/bin/python
-
-def gen_matrix(x, y = 0):
- if y == 0:
- y = x
- type = "mat" + str(x)
- if x != y:
- type = type + "x" + str(y)
- print type + " matrixCompMult(" + type + " x, " + type + " y)\n{"
- print " " + type + " z;"
-
- for i in range(x):
- print " z[" + str(i) + "] = x[" + str(i) + "] * y[" + str(i) + "];"
- print " return z;\n}"
-
-print "#version 120"
-# 1.10
-gen_matrix(2)
-gen_matrix(3)
-gen_matrix(4)
-
-# 1.20
-gen_matrix(2,3) # mat2x3 means 2 columns, 3 rows
-gen_matrix(3,2)
-gen_matrix(2,4)
-gen_matrix(4,2)
-gen_matrix(3,4)
-gen_matrix(4,3)
+++ /dev/null
-#!/usr/bin/python
-
-def gen(x, y):
- type = "mat" + str(x)
- if x != y:
- type = type + "x" + str(y)
- print type + " outerProduct(vec" + str(x) + " u, vec" + str(y) + " v)\n{"
- print " " + type + " m;"
-
- for i in range(x):
- print " m[" + str(i) + "] = v * u[" + str(i) + "];"
- print " return m;\n}"
-
-print "#version 120"
-gen(2,2)
-gen(2,3) # mat2x3 means 2 columns, 3 rows
-gen(2,4)
-gen(3,2)
-gen(3,3)
-gen(3,4)
-gen(4,2)
-gen(4,3)
-gen(4,4)
+++ /dev/null
-#!/usr/bin/python
-
-def gen(x, y):
- origtype = "mat" + str(x)
- trantype = "mat" + str(y)
- if x != y:
- origtype = origtype + "x" + str(y)
- trantype = trantype + "x" + str(x)
- print trantype + " transpose(" + origtype + " m)\n{"
- print " " + trantype + " t;"
-
- # The obvious implementation of transpose
- for i in range(x):
- for j in range(y):
- print " t[" + str(j) + "][" + str(i) + "] =",
- print "m[" + str(i) + "][" + str(j) + "];"
- print " return t;\n}"
-
-print "#version 120"
-gen(2,2)
-gen(2,3) # mat2x3 means 2 columns, 3 rows
-gen(2,4)
-gen(3,2)
-gen(3,3)
-gen(3,4)
-gen(4,2)
-gen(4,3)
-gen(4,4)
+++ /dev/null
-#!/usr/bin/python
-
-from os import path
-import sys
-
-def vec_type(g, size):
- if size == 1:
- if g == "i":
- return "int"
- elif g == "u":
- return "uint"
- return "float"
- return g + "vec" + str(size)
-
-# Get the base dimension - i.e. sampler3D gives 3
-# Array samplers also get +1 here since the layer is really an extra coordinate
-def get_coord_dim(sampler_type):
- if sampler_type[0].isdigit():
- coord_dim = int(sampler_type[0])
- elif sampler_type.startswith("Cube"):
- coord_dim = 3
- else:
- assert False ("coord_dim: invalid sampler_type: " + sampler_type)
-
- if sampler_type.find("Array") != -1:
- coord_dim += 1
- return coord_dim
-
-# Get the number of extra vector components (i.e. shadow comparitor)
-def get_extra_dim(sampler_type, use_proj, unused_fields):
- extra_dim = unused_fields
- if sampler_type.find("Shadow") != -1:
- extra_dim += 1
- if use_proj:
- extra_dim += 1
- return extra_dim
-
-def generate_sigs(g, tex_inst, sampler_type, use_proj = False, unused_fields = 0):
- coord_dim = get_coord_dim(sampler_type)
- extra_dim = get_extra_dim(sampler_type, use_proj, unused_fields)
-
- # Print parameters
- print " (signature " + g + "vec4"
- print " (parameters"
- print " (declare (in) " + g + "sampler" + sampler_type + " sampler)"
- print " (declare (in) " + vec_type("i" if tex_inst == "txf" else "", coord_dim + extra_dim) + " P)",
- if tex_inst == "txb":
- print "\n (declare (in) float bias)",
- elif tex_inst == "txl":
- print "\n (declare (in) float lod)",
- elif tex_inst == "txf":
- print "\n (declare (in) int lod)",
- elif tex_inst == "txd":
- grad_type = vec_type("", coord_dim)
- print "\n (declare (in) " + grad_type + " dPdx)",
- print "\n (declare (in) " + grad_type + " dPdy)",
-
- print ")\n ((return (" + tex_inst + " (var_ref sampler)",
-
- # Coordinate
- if extra_dim > 0:
- print "(swiz " + "xyzw"[:coord_dim] + " (var_ref P))",
- else:
- print "(var_ref P)",
-
- # Offset
- print "(0 0 0)",
-
- if tex_inst != "txf":
- # Projective divisor
- if use_proj:
- print "(swiz " + "xyzw"[coord_dim + extra_dim-1] + " (var_ref P))",
- else:
- print "1",
-
- # Shadow comparitor
- if sampler_type == "2DArrayShadow": # a special case:
- print "(swiz w (var_ref P))", # ...array layer is z; shadow is w
- elif sampler_type.endswith("Shadow"):
- print "(swiz z (var_ref P))",
- else:
- print "()",
-
- # Bias/explicit LOD/gradient:
- if tex_inst == "txb":
- print "(var_ref bias)",
- elif tex_inst == "txl" or tex_inst == "txf":
- print "(var_ref lod)",
- elif tex_inst == "txd":
- print "((var_ref dPdx) (var_ref dPdy))",
- print "))))\n"
-
-def generate_fiu_sigs(tex_inst, sampler_type, use_proj = False, unused_fields = 0):
- generate_sigs("", tex_inst, sampler_type, use_proj, unused_fields)
- generate_sigs("i", tex_inst, sampler_type, use_proj, unused_fields)
- generate_sigs("u", tex_inst, sampler_type, use_proj, unused_fields)
-
-builtins_dir = path.join(path.dirname(path.abspath(__file__)), "..")
-
-with open(path.join(builtins_dir, "130", "texture"), 'w') as sys.stdout:
- print "((function texture"
- generate_fiu_sigs("tex", "1D")
- generate_fiu_sigs("tex", "2D")
- generate_fiu_sigs("tex", "3D")
- generate_fiu_sigs("tex", "Cube")
- generate_fiu_sigs("tex", "1DArray")
- generate_fiu_sigs("tex", "2DArray")
- print "))"
-
-# txb variants are only allowed within a fragment shader (GLSL 1.30 p. 86)
-with open(path.join(builtins_dir, "130_fs", "texture"), 'w') as sys.stdout:
- print "((function texture"
- generate_fiu_sigs("txb", "1D")
- generate_fiu_sigs("txb", "2D")
- generate_fiu_sigs("txb", "3D")
- generate_fiu_sigs("txb", "Cube")
- generate_fiu_sigs("txb", "1DArray")
- generate_fiu_sigs("txb", "2DArray")
- print "))"
-
-with open(path.join(builtins_dir, "130", "textureProj"), 'w') as sys.stdout:
- print "((function textureProj"
- generate_fiu_sigs("tex", "1D", True)
- generate_fiu_sigs("tex", "1D", True, 2)
- generate_fiu_sigs("tex", "2D", True)
- generate_fiu_sigs("tex", "2D", True, 1)
- generate_fiu_sigs("tex", "3D", True)
- print "))"
-
-with open(path.join(builtins_dir, "130_fs", "textureProj"), 'w') as sys.stdout:
- print "((function textureProj"
- generate_fiu_sigs("txb", "1D", True)
- generate_fiu_sigs("txb", "1D", True, 2)
- generate_fiu_sigs("txb", "2D", True)
- generate_fiu_sigs("txb", "2D", True, 1)
- generate_fiu_sigs("txb", "3D", True)
- print "))"
-
-with open(path.join(builtins_dir, "130", "textureLod"), 'w') as sys.stdout:
- print "((function textureLod"
- generate_fiu_sigs("txl", "1D")
- generate_fiu_sigs("txl", "2D")
- generate_fiu_sigs("txl", "3D")
- generate_fiu_sigs("txl", "Cube")
- generate_fiu_sigs("txl", "1DArray")
- generate_fiu_sigs("txl", "2DArray")
- print "))"
-
-with open(path.join(builtins_dir, "130", "texelFetch"), 'w') as sys.stdout:
- print "((function texelFetch"
- generate_fiu_sigs("txf", "1D")
- generate_fiu_sigs("txf", "2D")
- generate_fiu_sigs("txf", "3D")
- generate_fiu_sigs("txf", "1DArray")
- generate_fiu_sigs("txf", "2DArray")
- print "))"
-
-with open(path.join(builtins_dir, "130", "textureProjLod"), 'w') as sys.stdout:
- print "((function textureLod"
- generate_fiu_sigs("txl", "1D", True)
- generate_fiu_sigs("txl", "1D", True, 2)
- generate_fiu_sigs("txl", "2D", True)
- generate_fiu_sigs("txl", "2D", True, 1)
- generate_fiu_sigs("txl", "3D", True)
- print "))"
-
-with open(path.join(builtins_dir, "130", "textureGrad"), 'w') as sys.stdout:
- print "((function textureGrad"
- generate_fiu_sigs("txd", "1D")
- generate_fiu_sigs("txd", "2D")
- generate_fiu_sigs("txd", "3D")
- generate_fiu_sigs("txd", "Cube")
- generate_fiu_sigs("txd", "1DArray")
- generate_fiu_sigs("txd", "2DArray")
- print ")\n)"
-
-with open(path.join(builtins_dir, "130", "textureProjGrad"), 'w') as sys.stdout:
- print "((function textureLod"
- generate_fiu_sigs("txd", "1D", True)
- generate_fiu_sigs("txd", "1D", True, 2)
- generate_fiu_sigs("txd", "2D", True)
- generate_fiu_sigs("txd", "2D", True, 1)
- generate_fiu_sigs("txd", "3D", True)
- print "))"
-
-# ARB_texture_rectangle extension
-with open(path.join(builtins_dir, "ARB_texture_rectangle", "textures"), 'w') as sys.stdout:
- print "((function texture2DRect"
- generate_sigs("", "tex", "2DRect")
- print ")\n (function shadow2DRect"
- generate_sigs("", "tex", "2DRectShadow")
- print "))"
-
-# EXT_texture_array extension
-with open(path.join(builtins_dir, "EXT_texture_array", "textures"), 'w') as sys.stdout:
- print "((function texture1DArray"
- generate_sigs("", "tex", "1DArray")
- print ")\n (function texture1DArrayLod"
- generate_sigs("", "txl", "1DArray")
- print ")\n (function texture2DArray"
- generate_sigs("", "tex", "2DArray")
- print ")\n (function texture2DArrayLod"
- generate_sigs("", "txl", "2DArray")
- print ")\n (function shadow1DArray"
- generate_sigs("", "tex", "1DArrayShadow")
- print ")\n (function shadow1DArrayLod"
- generate_sigs("", "txl", "1DArrayShadow")
- print ")\n (function shadow2DArray"
- generate_sigs("", "tex", "2DArrayShadow")
- print "))"
-
-with open(path.join(builtins_dir, "EXT_texture_array_fs", "textures"), 'w') as sys.stdout:
- print "((function texture1DArray"
- generate_sigs("", "txb", "1DArray") # MOVE TO _fs
- print ")\n (function texture2DArray"
- generate_sigs("", "txb", "2DArray") # MOVE TO _fs
- print ")\n (function shadow1DArray"
- generate_sigs("", "txb", "1DArrayShadow")
- print "))"
-
-# Deprecated (110/120 style) functions with silly names:
-with open(path.join(builtins_dir, "110", "textures"), 'w') as sys.stdout:
- print "((function texture1D"
- generate_sigs("", "tex", "1D")
- print ")\n (function texture1DLod"
- generate_sigs("", "txl", "1D")
- print ")\n (function texture1DProj"
- generate_sigs("", "tex", "1D", True)
- generate_sigs("", "tex", "1D", True, 2)
- print ")\n (function texture1DProjLod"
- generate_sigs("", "txl", "1D", True)
- generate_sigs("", "txl", "1D", True, 2)
- print ")\n (function texture2D"
- generate_sigs("", "tex", "2D")
- print ")\n(function texture2DLod"
- generate_sigs("", "txl", "2D")
- print ")\n (function texture2DProj"
- generate_sigs("", "tex", "2D", True)
- generate_sigs("", "tex", "2D", True, 1)
- print ")\n (function texture2DProjLod"
- generate_sigs("", "txl", "2D", True)
- generate_sigs("", "txl", "2D", True, 1)
- print ")\n (function texture3D"
- generate_sigs("", "tex", "3D")
- print ")\n (function texture3DLod"
- generate_sigs("", "txl", "3D")
- print ")\n (function texture3DProj"
- generate_sigs("", "tex", "3D", True)
- print ")\n (function texture3DProjLod"
- generate_sigs("", "txl", "3D", True)
- print ")\n (function textureCube"
- generate_sigs("", "tex", "Cube")
- print ")\n (function textureCubeLod"
- generate_sigs("", "txl", "Cube")
- print ")\n (function shadow1D"
- generate_sigs("", "tex", "1DShadow", False, 1)
- print ")\n (function shadow1DLod"
- generate_sigs("", "txl", "1DShadow", False, 1)
- print ")\n (function shadow1DProj"
- generate_sigs("", "tex", "1DShadow", True, 1)
- print ")\n (function shadow1DProjLod"
- generate_sigs("", "txl", "1DShadow", True, 1)
- print ")\n (function shadow2D"
- generate_sigs("", "tex", "2DShadow")
- print ")\n (function shadow2DLod"
- generate_sigs("", "txl", "2DShadow")
- print ")\n (function shadow2DProj"
- generate_sigs("", "tex", "2DShadow", True)
- print ")\n (function shadow2DProjLod"
- generate_sigs("", "txl", "2DShadow", True)
- print "))"
-
-with open(path.join(builtins_dir, "110_fs", "textures"), 'w') as sys.stdout:
- print "((function texture1D"
- generate_sigs("", "txb", "1D")
- print ")\n (function texture1DProj"
- generate_sigs("", "txb", "1D", True)
- generate_sigs("", "txb", "1D", True, 2)
- print ")\n (function texture2D"
- generate_sigs("", "txb", "2D")
- print ")\n (function texture2DProj"
- generate_sigs("", "txb", "2D", True)
- generate_sigs("", "txb", "2D", True, 1)
- print ")\n (function texture3D"
- generate_sigs("", "txb", "3D")
- print ")\n (function texture3DProj"
- generate_sigs("", "txb", "3D", True)
- print ")\n (function textureCube"
- generate_sigs("", "txb", "Cube")
- print ")\n (function shadow1D"
- generate_sigs("", "txb", "1DShadow", False, 1)
- print ")\n (function shadow1DProj"
- generate_sigs("", "txb", "1DShadow", True, 1)
- print ")\n (function shadow2D"
- generate_sigs("", "txb", "2DShadow")
- print ")\n (function shadow2DProj"
- generate_sigs("", "txb", "2DShadow", True)
- print "))"
+++ /dev/null
-# -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.61)
-AC_INIT(glsl, XXXXX, idr@freedesktop.org, glsl)
-AC_CONFIG_SRCDIR([Makefile.am])
-AM_CONFIG_HEADER([config.h])
-AC_CONFIG_FILES([glcpp/Makefile])
-
-AM_INIT_AUTOMAKE
-LT_INIT
-
-AM_MAINTAINER_MODE
-
-# Checks for programs.
-AC_PROG_CXX
-AC_PROG_CC
-AC_PROG_MAKE_SET
-AC_PROG_YACC
-AC_PROG_LEX
-
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-# Checks for libraries.
-
-# Checks for header files.
-
-# Checks for typedefs, structures, and compiler characteristics.
-
-# Checks for library functions.
-AC_HEADER_STDC
-
-AH_TOP([#ifndef GLSL_CONFIG_H
-#define GLSL_CONFIG_H])
-AH_BOTTOM([#endif /* GLSL_CONFIG_H */])
-
-PKG_CHECK_MODULES([talloc], [talloc >= 2.0])
-
-AC_ARG_ENABLE([debug],
- [AS_HELP_STRING([--enable-debug],
- [use debug compiler flags and macros @<:@default=disabled@:>@])],
- [enable_debug="$enableval"],
- [enable_debug=no]
-)
-if test "x$enable_debug" = xyes; then
- DEFINES="$DEFINES -DDEBUG"
- if test "x$GCC" = xyes; then
- # Remove any -g or -O flags from the command line
- CFLAGS=[`echo $CFLAGS | sed 's/-g[^ \t]*[ \t]*//g;s/-O[^ \t]*[ \t]*//g'`]
- CFLAGS="$CFLAGS -O0 -ggdb3 -fstack-protector -D_FORTIFY_SOURCE=2"
- fi
- if test "x$GXX" = xyes; then
- # Remove any -g flags from the command line
- CXXFLAGS=[`echo $CXXFLAGS | sed 's/-g[^ \t]*[ \t]*//g;s/-O[^ \t]*[ \t]*//g'`]
- CXXFLAGS="$CXXFLAGS -O0 -ggdb3 -fstack-protector -D_FORTIFY_SOURCE=2"
- fi
-fi
-
-if test "x$GXX" = xyes ; then
- WARN="-Wall -Wextra -Wunsafe-loop-optimizations -Wstack-protector"
-else
- WARN=""
-fi
-
-CFLAGS="$CFLAGS $WARN"
-CXXFLAGS="$CXXFLAGS $WARN"
-YFLAGS="-d -v"
-
-AC_OUTPUT([Makefile])
+++ /dev/null
-glcpp
-glcpp-lex.c
-glcpp-parse.c
-glcpp-parse.h
-glcpp-parse.output
-*.o
-*.lo
-*.la
-.libs
-*~
-tests/*.out
+++ /dev/null
-# Copyright © 2010 Intel Corporation
-# 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
-# on 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
-# AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR 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.
-
-noinst_LTLIBRARIES = libglcpp.la
-libglcpp_la_SOURCES = \
- glcpp-lex.l \
- glcpp-parse.y \
- glcpp.h \
- hash_table.c \
- pp.c \
- xtalloc.c
-
-BUILT_SOURCES = glcpp-parse.h glcpp-parse.c glcpp-lex.c
-CLEANFILES = $(BUILT_SOURCES)
-
-glcpp-parse.h: glcpp-parse.c
-
-bin_PROGRAMS = glcpp
-glcpp_LDADD = libglcpp.la
-glcpp_LDFLAGS = @LDFLAGS@ $(talloc_LIBS)
-glcpp_SOURCES = glcpp.c
-
-.l.c:
- $(LEXCOMPILE) --outfile="$@" $<
-
-test: glcpp
- @(cd tests; ./glcpp-test)
+++ /dev/null
-glcpp -- GLSL "C" preprocessor
-
-This is a simple preprocessor designed to provide the preprocessing
-needs of the GLSL language. The requirements for this preprocessor are
-specified in the GLSL 1.30 specification availble from:
-
-http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.30.08.pdf
-
-This specification is not precise on some semantics, (for example,
-#define and #if), defining these merely "as is standard for C++
-preprocessors". To fill in these details, I've been using the C99
-standard (for which I had a convenient copy) as available from:
-
-http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
-
-Known limitations
------------------
-Macro invocations cannot include embedded newlines.
-
-The __LINE__, __FILE__, and __VERSION__ macros are not yet supported.
-
-The argument of the 'defined' operator cannot yet include enclosing
-parentheses.
-
-The #error, #pragma, #extension, #version, and #line macros are not
-yet supported.
-
-A file that ends with a function-like macro name as the last
-non-whitespace token will result in a parse error, (where it should be
-passed through as is).
\ No newline at end of file
+++ /dev/null
-%{
-/*
- * 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 <stdio.h>
-#include <string.h>
-
-#include "glcpp.h"
-#include "glcpp-parse.h"
-
-#define YY_USER_ACTION \
- do { \
- yylloc->source = 0; \
- yylloc->first_column = yycolumn + 1; \
- yylloc->first_line = yylineno; \
- yycolumn += yyleng; \
- } while(0);
-%}
-
-%option bison-bridge bison-locations reentrant noyywrap
-%option extra-type="glcpp_parser_t *"
-%option prefix="glcpp_"
-%option stack
-
-%x DONE COMMENT
-
-SPACE [[:space:]]
-NONSPACE [^[:space:]]
-NEWLINE [\n]
-HSPACE [ \t]
-HASH ^{HSPACE}*#{HSPACE}*
-IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
-PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
-OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
-
-DECIMAL_INTEGER [1-9][0-9]*[uU]?
-OCTAL_INTEGER 0[0-7]*[uU]?
-HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
-
-%%
-
- /* Single-line comments */
-"//"[^\n]*\n {
- yylineno++;
- yycolumn = 0;
- return NEWLINE;
-}
-
- /* Multi-line comments */
-"/*" { yy_push_state(COMMENT, yyscanner); }
-<COMMENT>[^*\n]*
-<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; }
-<COMMENT>"*"+[^*/\n]*
-<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; }
-<COMMENT>"*"+"/" {
- yy_pop_state(yyscanner);
- if (yyextra->space_tokens)
- return SPACE;
-}
-
- /* glcpp doesn't handle #extension, #version, or #pragma directives.
- * Simply pass them through to the main compiler's lexer/parser. */
-{HASH}(extension|version|pragma)[^\n]+ {
- yylval->str = xtalloc_strdup (yyextra, yytext);
- yylineno++;
- yycolumn = 0;
- return OTHER;
-}
-
-{HASH}ifdef/.*\n {
- yyextra->space_tokens = 0;
- return HASH_IFDEF;
-}
-
-{HASH}ifndef/.*\n {
- yyextra->space_tokens = 0;
- return HASH_IFNDEF;
-}
-
-{HASH}if{HSPACE}/.*\n {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_IF;
-}
-
-{HASH}elif/.*\n {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_ELIF;
-}
-
-{HASH}else/.*\n {
- yyextra->space_tokens = 0;
- return HASH_ELSE;
-}
-
-{HASH}endif/.*\n {
- yyextra->space_tokens = 0;
- return HASH_ENDIF;
-}
-
- /* When skipping (due to an #if 0 or similar) consume anything
- * up to a newline. We do this less priroty than any
- * #if-related directive (#if, #elif, #else, #endif), but with
- * more priority than any other directive or token to avoid
- * any side-effects from skipped content.
- *
- * We use the lexing_if flag to avoid skipping any part of an
- * if conditional expression. */
-[^\n]+/\n {
- /* Since this rule always matches, YY_USER_ACTION gets called for it,
- * wrongly incrementing yycolumn. We undo that effect here. */
- yycolumn -= yyleng;
- if (yyextra->lexing_if ||
- yyextra->skip_stack == NULL ||
- yyextra->skip_stack->type == SKIP_NO_SKIP)
- {
- REJECT;
- }
-}
-
-{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
- yyextra->space_tokens = 0;
- return HASH_DEFINE_FUNC;
-}
-
-{HASH}define {
- yyextra->space_tokens = 0;
- return HASH_DEFINE_OBJ;
-}
-
-{HASH}undef {
- yyextra->space_tokens = 0;
- return HASH_UNDEF;
-}
-
-{HASH} {
- yyextra->space_tokens = 0;
- return HASH;
-}
-
-{DECIMAL_INTEGER} {
- yylval->str = xtalloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-{OCTAL_INTEGER} {
- yylval->str = xtalloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-{HEXADECIMAL_INTEGER} {
- yylval->str = xtalloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-"<<" {
- return LEFT_SHIFT;
-}
-
-">>" {
- return RIGHT_SHIFT;
-}
-
-"<=" {
- return LESS_OR_EQUAL;
-}
-
-">=" {
- return GREATER_OR_EQUAL;
-}
-
-"==" {
- return EQUAL;
-}
-
-"!=" {
- return NOT_EQUAL;
-}
-
-"&&" {
- return AND;
-}
-
-"||" {
- return OR;
-}
-
-"##" {
- return PASTE;
-}
-
-"defined" {
- return DEFINED;
-}
-
-{IDENTIFIER} {
- yylval->str = xtalloc_strdup (yyextra, yytext);
- return IDENTIFIER;
-}
-
-{PUNCTUATION} {
- return yytext[0];
-}
-
-{OTHER}+ {
- yylval->str = xtalloc_strdup (yyextra, yytext);
- return OTHER;
-}
-
-{HSPACE}+ {
- if (yyextra->space_tokens) {
- return SPACE;
- }
-}
-
-\n {
- yyextra->lexing_if = 0;
- yylineno++;
- yycolumn = 0;
- return NEWLINE;
-}
-
- /* Handle missing newline at EOF. */
-<INITIAL><<EOF>> {
- BEGIN DONE; /* Don't keep matching this rule forever. */
- yyextra->lexing_if = 0;
- return NEWLINE;
-}
-
-%%
-
-void
-glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
-{
- yy_scan_string(shader, parser->scanner);
-}
+++ /dev/null
-%{
-/*
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <inttypes.h>
-
-#include "glcpp.h"
-
-#define glcpp_print(stream, str) stream = talloc_strdup_append(stream, str)
-#define glcpp_printf(stream, fmt, args...) \
- stream = talloc_asprintf_append(stream, fmt, args)
-
-static void
-yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
-
-static void
-_define_object_macro (glcpp_parser_t *parser,
- YYLTYPE *loc,
- const char *macro,
- token_list_t *replacements);
-
-static void
-_define_function_macro (glcpp_parser_t *parser,
- YYLTYPE *loc,
- const char *macro,
- string_list_t *parameters,
- token_list_t *replacements);
-
-static string_list_t *
-_string_list_create (void *ctx);
-
-static void
-_string_list_append_item (string_list_t *list, const char *str);
-
-static int
-_string_list_contains (string_list_t *list, const char *member, int *index);
-
-static int
-_string_list_length (string_list_t *list);
-
-static argument_list_t *
-_argument_list_create (void *ctx);
-
-static void
-_argument_list_append (argument_list_t *list, token_list_t *argument);
-
-static int
-_argument_list_length (argument_list_t *list);
-
-static token_list_t *
-_argument_list_member_at (argument_list_t *list, int index);
-
-/* Note: This function talloc_steal()s the str pointer. */
-static token_t *
-_token_create_str (void *ctx, int type, char *str);
-
-static token_t *
-_token_create_ival (void *ctx, int type, int ival);
-
-static token_list_t *
-_token_list_create (void *ctx);
-
-/* Note: This function adds a talloc_reference() to token.
- *
- * You may want to talloc_unlink any current reference if you no
- * longer need it. */
-static void
-_token_list_append (token_list_t *list, token_t *token);
-
-static void
-_token_list_append_list (token_list_t *list, token_list_t *tail);
-
-static active_list_t *
-_active_list_push (active_list_t *list,
- const char *identifier,
- token_node_t *marker);
-
-static active_list_t *
-_active_list_pop (active_list_t *list);
-
-int
-_active_list_contains (active_list_t *list, const char *identifier);
-
-static void
-_glcpp_parser_expand_token_list (glcpp_parser_t *parser,
- token_list_t *list);
-
-static void
-_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
- token_list_t *list);
-
-static void
-_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
- int condition);
-
-static void
-_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
- const char *type, int condition);
-
-static void
-_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc);
-
-#define yylex glcpp_parser_lex
-
-static int
-glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser);
-
-static void
-glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list);
-
-%}
-
-%pure-parser
-%error-verbose
-%locations
-
-%parse-param {glcpp_parser_t *parser}
-%lex-param {glcpp_parser_t *parser}
-
-%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE_FUNC HASH_DEFINE_OBJ HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF HASH_UNDEF IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING NEWLINE OTHER PLACEHOLDER SPACE
-%token PASTE
-%type <ival> expression INTEGER operator SPACE
-%type <str> IDENTIFIER INTEGER_STRING OTHER
-%type <string_list> identifier_list
-%type <token> preprocessing_token conditional_token
-%type <token_list> pp_tokens replacement_list text_line conditional_tokens
-%left OR
-%left AND
-%left '|'
-%left '^'
-%left '&'
-%left EQUAL NOT_EQUAL
-%left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL
-%left LEFT_SHIFT RIGHT_SHIFT
-%left '+' '-'
-%left '*' '/' '%'
-%right UNARY
-
-%%
-
-input:
- /* empty */
-| input line
-;
-
-line:
- control_line {
- glcpp_print(parser->output, "\n");
- }
-| text_line {
- _glcpp_parser_print_expanded_token_list (parser, $1);
- glcpp_print(parser->output, "\n");
- talloc_free ($1);
- }
-| expanded_line
-| HASH non_directive
-;
-
-expanded_line:
- IF_EXPANDED expression NEWLINE {
- _glcpp_parser_skip_stack_push_if (parser, & @1, $2);
- }
-| ELIF_EXPANDED expression NEWLINE {
- _glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2);
- }
-;
-
-control_line:
- HASH_DEFINE_OBJ IDENTIFIER replacement_list NEWLINE {
- _define_object_macro (parser, & @2, $2, $3);
- }
-| HASH_DEFINE_FUNC IDENTIFIER '(' ')' replacement_list NEWLINE {
- _define_function_macro (parser, & @2, $2, NULL, $5);
- }
-| HASH_DEFINE_FUNC IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE {
- _define_function_macro (parser, & @2, $2, $4, $6);
- }
-| HASH_UNDEF IDENTIFIER NEWLINE {
- macro_t *macro = hash_table_find (parser->defines, $2);
- if (macro) {
- /* XXX: Need hash table to support a real way
- * to remove an element rather than prefixing
- * a new node with data of NULL like this. */
- hash_table_insert (parser->defines, NULL, $2);
- talloc_free (macro);
- }
- talloc_free ($2);
- }
-| HASH_IF conditional_tokens NEWLINE {
- token_list_t *expanded;
- token_t *token;
-
- expanded = _token_list_create (parser);
- token = _token_create_ival (parser, IF_EXPANDED, IF_EXPANDED);
- _token_list_append (expanded, token);
- talloc_unlink (parser, token);
- _glcpp_parser_expand_token_list (parser, $2);
- _token_list_append_list (expanded, $2);
- glcpp_parser_lex_from (parser, expanded);
- }
-| HASH_IFDEF IDENTIFIER junk NEWLINE {
- macro_t *macro = hash_table_find (parser->defines, $2);
- talloc_free ($2);
- _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
- }
-| HASH_IFNDEF IDENTIFIER junk NEWLINE {
- macro_t *macro = hash_table_find (parser->defines, $2);
- talloc_free ($2);
- _glcpp_parser_skip_stack_push_if (parser, & @1, macro == NULL);
- }
-| HASH_ELIF conditional_tokens NEWLINE {
- token_list_t *expanded;
- token_t *token;
-
- expanded = _token_list_create (parser);
- token = _token_create_ival (parser, ELIF_EXPANDED, ELIF_EXPANDED);
- _token_list_append (expanded, token);
- talloc_unlink (parser, token);
- _glcpp_parser_expand_token_list (parser, $2);
- _token_list_append_list (expanded, $2);
- glcpp_parser_lex_from (parser, expanded);
- }
-| HASH_ELIF NEWLINE {
- /* #elif without an expression results in a warning if the
- * condition doesn't matter (we just handled #if 1 or such)
- * but an error otherwise. */
- if (parser->skip_stack != NULL && parser->skip_stack->type == SKIP_NO_SKIP) {
- parser->skip_stack->type = SKIP_TO_ENDIF;
- glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
- } else {
- glcpp_error(& @1, parser, "#elif needs an expression");
- }
- }
-| HASH_ELSE NEWLINE {
- _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
- }
-| HASH_ENDIF NEWLINE {
- _glcpp_parser_skip_stack_pop (parser, & @1);
- }
-| HASH NEWLINE
-;
-
-expression:
- INTEGER_STRING {
- if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) {
- $$ = strtoll ($1 + 2, NULL, 16);
- } else if ($1[0] == '0') {
- $$ = strtoll ($1, NULL, 8);
- } else {
- $$ = strtoll ($1, NULL, 10);
- }
- }
-| INTEGER {
- $$ = $1;
- }
-| expression OR expression {
- $$ = $1 || $3;
- }
-| expression AND expression {
- $$ = $1 && $3;
- }
-| expression '|' expression {
- $$ = $1 | $3;
- }
-| expression '^' expression {
- $$ = $1 ^ $3;
- }
-| expression '&' expression {
- $$ = $1 & $3;
- }
-| expression NOT_EQUAL expression {
- $$ = $1 != $3;
- }
-| expression EQUAL expression {
- $$ = $1 == $3;
- }
-| expression GREATER_OR_EQUAL expression {
- $$ = $1 >= $3;
- }
-| expression LESS_OR_EQUAL expression {
- $$ = $1 <= $3;
- }
-| expression '>' expression {
- $$ = $1 > $3;
- }
-| expression '<' expression {
- $$ = $1 < $3;
- }
-| expression RIGHT_SHIFT expression {
- $$ = $1 >> $3;
- }
-| expression LEFT_SHIFT expression {
- $$ = $1 << $3;
- }
-| expression '-' expression {
- $$ = $1 - $3;
- }
-| expression '+' expression {
- $$ = $1 + $3;
- }
-| expression '%' expression {
- $$ = $1 % $3;
- }
-| expression '/' expression {
- $$ = $1 / $3;
- }
-| expression '*' expression {
- $$ = $1 * $3;
- }
-| '!' expression %prec UNARY {
- $$ = ! $2;
- }
-| '~' expression %prec UNARY {
- $$ = ~ $2;
- }
-| '-' expression %prec UNARY {
- $$ = - $2;
- }
-| '+' expression %prec UNARY {
- $$ = + $2;
- }
-| '(' expression ')' {
- $$ = $2;
- }
-;
-
-identifier_list:
- IDENTIFIER {
- $$ = _string_list_create (parser);
- _string_list_append_item ($$, $1);
- talloc_steal ($$, $1);
- }
-| identifier_list ',' IDENTIFIER {
- $$ = $1;
- _string_list_append_item ($$, $3);
- talloc_steal ($$, $3);
- }
-;
-
-text_line:
- NEWLINE { $$ = NULL; }
-| pp_tokens NEWLINE
-;
-
-non_directive:
- pp_tokens NEWLINE {
- yyerror (& @1, parser, "Invalid tokens after #");
- }
-;
-
-replacement_list:
- /* empty */ { $$ = NULL; }
-| pp_tokens
-;
-
-junk:
- /* empty */
-| pp_tokens {
- glcpp_warning(&@1, parser, "extra tokens at end of directive");
- }
-;
-
-conditional_token:
- /* Handle "defined" operator */
- DEFINED IDENTIFIER {
- int v = hash_table_find (parser->defines, $2) ? 1 : 0;
- $$ = _token_create_ival (parser, INTEGER, v);
- }
-| DEFINED '(' IDENTIFIER ')' {
- int v = hash_table_find (parser->defines, $3) ? 1 : 0;
- $$ = _token_create_ival (parser, INTEGER, v);
- }
-| preprocessing_token
-;
-
-conditional_tokens:
- /* Exactly the same as pp_tokens, but using conditional_token */
- conditional_token {
- parser->space_tokens = 1;
- $$ = _token_list_create (parser);
- _token_list_append ($$, $1);
- talloc_unlink (parser, $1);
- }
-| conditional_tokens conditional_token {
- $$ = $1;
- _token_list_append ($$, $2);
- talloc_unlink (parser, $2);
- }
-;
-
-pp_tokens:
- preprocessing_token {
- parser->space_tokens = 1;
- $$ = _token_list_create (parser);
- _token_list_append ($$, $1);
- talloc_unlink (parser, $1);
- }
-| pp_tokens preprocessing_token {
- $$ = $1;
- _token_list_append ($$, $2);
- talloc_unlink (parser, $2);
- }
-;
-
-preprocessing_token:
- IDENTIFIER {
- $$ = _token_create_str (parser, IDENTIFIER, $1);
- $$->location = yylloc;
- }
-| INTEGER_STRING {
- $$ = _token_create_str (parser, INTEGER_STRING, $1);
- $$->location = yylloc;
- }
-| operator {
- $$ = _token_create_ival (parser, $1, $1);
- $$->location = yylloc;
- }
-| OTHER {
- $$ = _token_create_str (parser, OTHER, $1);
- $$->location = yylloc;
- }
-| SPACE {
- $$ = _token_create_ival (parser, SPACE, SPACE);
- $$->location = yylloc;
- }
-;
-
-operator:
- '[' { $$ = '['; }
-| ']' { $$ = ']'; }
-| '(' { $$ = '('; }
-| ')' { $$ = ')'; }
-| '{' { $$ = '{'; }
-| '}' { $$ = '}'; }
-| '.' { $$ = '.'; }
-| '&' { $$ = '&'; }
-| '*' { $$ = '*'; }
-| '+' { $$ = '+'; }
-| '-' { $$ = '-'; }
-| '~' { $$ = '~'; }
-| '!' { $$ = '!'; }
-| '/' { $$ = '/'; }
-| '%' { $$ = '%'; }
-| LEFT_SHIFT { $$ = LEFT_SHIFT; }
-| RIGHT_SHIFT { $$ = RIGHT_SHIFT; }
-| '<' { $$ = '<'; }
-| '>' { $$ = '>'; }
-| LESS_OR_EQUAL { $$ = LESS_OR_EQUAL; }
-| GREATER_OR_EQUAL { $$ = GREATER_OR_EQUAL; }
-| EQUAL { $$ = EQUAL; }
-| NOT_EQUAL { $$ = NOT_EQUAL; }
-| '^' { $$ = '^'; }
-| '|' { $$ = '|'; }
-| AND { $$ = AND; }
-| OR { $$ = OR; }
-| ';' { $$ = ';'; }
-| ',' { $$ = ','; }
-| '=' { $$ = '='; }
-| PASTE { $$ = PASTE; }
-| DEFINED { $$ = DEFINED; }
-;
-
-%%
-
-string_list_t *
-_string_list_create (void *ctx)
-{
- string_list_t *list;
-
- list = xtalloc (ctx, string_list_t);
- list->head = NULL;
- list->tail = NULL;
-
- return list;
-}
-
-void
-_string_list_append_item (string_list_t *list, const char *str)
-{
- string_node_t *node;
-
- node = xtalloc (list, string_node_t);
- node->str = xtalloc_strdup (node, str);
-
- node->next = NULL;
-
- if (list->head == NULL) {
- list->head = node;
- } else {
- list->tail->next = node;
- }
-
- list->tail = node;
-}
-
-int
-_string_list_contains (string_list_t *list, const char *member, int *index)
-{
- string_node_t *node;
- int i;
-
- if (list == NULL)
- return 0;
-
- for (i = 0, node = list->head; node; i++, node = node->next) {
- if (strcmp (node->str, member) == 0) {
- if (index)
- *index = i;
- return 1;
- }
- }
-
- return 0;
-}
-
-int
-_string_list_length (string_list_t *list)
-{
- int length = 0;
- string_node_t *node;
-
- if (list == NULL)
- return 0;
-
- for (node = list->head; node; node = node->next)
- length++;
-
- return length;
-}
-
-argument_list_t *
-_argument_list_create (void *ctx)
-{
- argument_list_t *list;
-
- list = xtalloc (ctx, argument_list_t);
- list->head = NULL;
- list->tail = NULL;
-
- return list;
-}
-
-void
-_argument_list_append (argument_list_t *list, token_list_t *argument)
-{
- argument_node_t *node;
-
- node = xtalloc (list, argument_node_t);
- node->argument = argument;
-
- node->next = NULL;
-
- if (list->head == NULL) {
- list->head = node;
- } else {
- list->tail->next = node;
- }
-
- list->tail = node;
-}
-
-int
-_argument_list_length (argument_list_t *list)
-{
- int length = 0;
- argument_node_t *node;
-
- if (list == NULL)
- return 0;
-
- for (node = list->head; node; node = node->next)
- length++;
-
- return length;
-}
-
-token_list_t *
-_argument_list_member_at (argument_list_t *list, int index)
-{
- argument_node_t *node;
- int i;
-
- if (list == NULL)
- return NULL;
-
- node = list->head;
- for (i = 0; i < index; i++) {
- node = node->next;
- if (node == NULL)
- break;
- }
-
- if (node)
- return node->argument;
-
- return NULL;
-}
-
-/* Note: This function talloc_steal()s the str pointer. */
-token_t *
-_token_create_str (void *ctx, int type, char *str)
-{
- token_t *token;
-
- token = xtalloc (ctx, token_t);
- token->type = type;
- token->value.str = talloc_steal (token, str);
-
- return token;
-}
-
-token_t *
-_token_create_ival (void *ctx, int type, int ival)
-{
- token_t *token;
-
- token = xtalloc (ctx, token_t);
- token->type = type;
- token->value.ival = ival;
-
- return token;
-}
-
-token_list_t *
-_token_list_create (void *ctx)
-{
- token_list_t *list;
-
- list = xtalloc (ctx, token_list_t);
- list->head = NULL;
- list->tail = NULL;
- list->non_space_tail = NULL;
-
- return list;
-}
-
-void
-_token_list_append (token_list_t *list, token_t *token)
-{
- token_node_t *node;
-
- node = xtalloc (list, token_node_t);
- node->token = xtalloc_reference (list, token);
-
- node->next = NULL;
-
- if (list->head == NULL) {
- list->head = node;
- } else {
- list->tail->next = node;
- }
-
- list->tail = node;
- if (token->type != SPACE)
- list->non_space_tail = node;
-}
-
-void
-_token_list_append_list (token_list_t *list, token_list_t *tail)
-{
- if (tail == NULL || tail->head == NULL)
- return;
-
- if (list->head == NULL) {
- list->head = tail->head;
- } else {
- list->tail->next = tail->head;
- }
-
- list->tail = tail->tail;
- list->non_space_tail = tail->non_space_tail;
-}
-
-token_list_t *
-_token_list_copy (void *ctx, token_list_t *other)
-{
- token_list_t *copy;
- token_node_t *node;
-
- if (other == NULL)
- return NULL;
-
- copy = _token_list_create (ctx);
- for (node = other->head; node; node = node->next)
- _token_list_append (copy, node->token);
-
- return copy;
-}
-
-void
-_token_list_trim_trailing_space (token_list_t *list)
-{
- token_node_t *tail, *next;
-
- if (list->non_space_tail) {
- tail = list->non_space_tail->next;
- list->non_space_tail->next = NULL;
- list->tail = list->non_space_tail;
-
- while (tail) {
- next = tail->next;
- talloc_free (tail);
- tail = next;
- }
- }
-}
-
-static void
-_token_print (char **out, token_t *token)
-{
- if (token->type < 256) {
- glcpp_printf (*out, "%c", token->type);
- return;
- }
-
- switch (token->type) {
- case INTEGER:
- glcpp_printf (*out, "%" PRIxMAX, token->value.ival);
- break;
- case IDENTIFIER:
- case INTEGER_STRING:
- case OTHER:
- glcpp_print (*out, token->value.str);
- break;
- case SPACE:
- glcpp_print (*out, " ");
- break;
- case LEFT_SHIFT:
- glcpp_print (*out, "<<");
- break;
- case RIGHT_SHIFT:
- glcpp_print (*out, ">>");
- break;
- case LESS_OR_EQUAL:
- glcpp_print (*out, "<=");
- break;
- case GREATER_OR_EQUAL:
- glcpp_print (*out, ">=");
- break;
- case EQUAL:
- glcpp_print (*out, "==");
- break;
- case NOT_EQUAL:
- glcpp_print (*out, "!=");
- break;
- case AND:
- glcpp_print (*out, "&&");
- break;
- case OR:
- glcpp_print (*out, "||");
- break;
- case PASTE:
- glcpp_print (*out, "##");
- break;
- case COMMA_FINAL:
- glcpp_print (*out, ",");
- break;
- case PLACEHOLDER:
- /* Nothing to print. */
- break;
- default:
- assert(!"Error: Don't know how to print token.");
- break;
- }
-}
-
-/* Return a new token (talloc()ed off of 'token') formed by pasting
- * 'token' and 'other'. Note that this function may return 'token' or
- * 'other' directly rather than allocating anything new.
- *
- * Caution: Only very cursory error-checking is performed to see if
- * the final result is a valid single token. */
-static token_t *
-_token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
-{
- token_t *combined = NULL;
-
- /* Pasting a placeholder onto anything makes no change. */
- if (other->type == PLACEHOLDER)
- return token;
-
- /* When 'token' is a placeholder, just return 'other'. */
- if (token->type == PLACEHOLDER)
- return other;
-
- /* A very few single-character punctuators can be combined
- * with another to form a multi-character punctuator. */
- switch (token->type) {
- case '<':
- if (other->type == '<')
- combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT);
- else if (other->type == '=')
- combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL);
- break;
- case '>':
- if (other->type == '>')
- combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT);
- else if (other->type == '=')
- combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
- break;
- case '=':
- if (other->type == '=')
- combined = _token_create_ival (token, EQUAL, EQUAL);
- break;
- case '!':
- if (other->type == '=')
- combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL);
- break;
- case '&':
- if (other->type == '&')
- combined = _token_create_ival (token, AND, AND);
- break;
- case '|':
- if (other->type == '|')
- combined = _token_create_ival (token, OR, OR);
- break;
- }
-
- if (combined != NULL) {
- /* Inherit the location from the first token */
- combined->location = token->location;
- return combined;
- }
-
- /* Two string-valued tokens can usually just be mashed
- * together.
- *
- * XXX: This isn't actually legitimate. Several things here
- * should result in a diagnostic since the result cannot be a
- * valid, single pre-processing token. For example, pasting
- * "123" and "abc" is not legal, but we don't catch that
- * here. */
- if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING) &&
- (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING))
- {
- char *str;
-
- str = xtalloc_asprintf (token, "%s%s",
- token->value.str, other->value.str);
- combined = _token_create_str (token, token->type, str);
- combined->location = token->location;
- return combined;
- }
-
- glcpp_error (&token->location, parser, "");
- glcpp_print (parser->info_log, "Pasting \"");
- _token_print (&parser->info_log, token);
- glcpp_print (parser->info_log, "\" and \"");
- _token_print (&parser->info_log, other);
- glcpp_print (parser->info_log, "\" does not give a valid preprocessing token.\n");
-
- return token;
-}
-
-static void
-_token_list_print (glcpp_parser_t *parser, token_list_t *list)
-{
- token_node_t *node;
-
- if (list == NULL)
- return;
-
- for (node = list->head; node; node = node->next)
- _token_print (&parser->output, node->token);
-}
-
-void
-yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error)
-{
- glcpp_error(locp, parser, "%s", error);
-}
-
-glcpp_parser_t *
-glcpp_parser_create (void)
-{
- glcpp_parser_t *parser;
-
- parser = xtalloc (NULL, glcpp_parser_t);
-
- glcpp_lex_init_extra (parser, &parser->scanner);
- parser->defines = hash_table_ctor (32, hash_table_string_hash,
- hash_table_string_compare);
- parser->active = NULL;
- parser->lexing_if = 0;
- parser->space_tokens = 1;
- parser->newline_as_space = 0;
- parser->in_control_line = 0;
- parser->paren_count = 0;
-
- parser->skip_stack = NULL;
-
- parser->lex_from_list = NULL;
- parser->lex_from_node = NULL;
-
- parser->output = talloc_strdup(parser, "");
- parser->info_log = talloc_strdup(parser, "");
- parser->error = 0;
-
- return parser;
-}
-
-int
-glcpp_parser_parse (glcpp_parser_t *parser)
-{
- return yyparse (parser);
-}
-
-void
-glcpp_parser_destroy (glcpp_parser_t *parser)
-{
- if (parser->skip_stack)
- glcpp_error (&parser->skip_stack->loc, parser, "Unterminated #if\n");
- glcpp_lex_destroy (parser->scanner);
- hash_table_dtor (parser->defines);
- talloc_free (parser);
-}
-
-typedef enum function_status
-{
- FUNCTION_STATUS_SUCCESS,
- FUNCTION_NOT_A_FUNCTION,
- FUNCTION_UNBALANCED_PARENTHESES
-} function_status_t;
-
-/* Find a set of function-like macro arguments by looking for a
- * balanced set of parentheses.
- *
- * When called, 'node' should be the opening-parenthesis token, (or
- * perhaps preceeding SPACE tokens). Upon successful return *last will
- * be the last consumed node, (corresponding to the closing right
- * parenthesis).
- *
- * Return values:
- *
- * FUNCTION_STATUS_SUCCESS:
- *
- * Successfully parsed a set of function arguments.
- *
- * FUNCTION_NOT_A_FUNCTION:
- *
- * Macro name not followed by a '('. This is not an error, but
- * simply that the macro name should be treated as a non-macro.
- *
- * FUNCTION_UNBALANCED_PARENTHESES
- *
- * Macro name is not followed by a balanced set of parentheses.
- */
-static function_status_t
-_arguments_parse (argument_list_t *arguments,
- token_node_t *node,
- token_node_t **last)
-{
- token_list_t *argument;
- int paren_count;
-
- node = node->next;
-
- /* Ignore whitespace before first parenthesis. */
- while (node && node->token->type == SPACE)
- node = node->next;
-
- if (node == NULL || node->token->type != '(')
- return FUNCTION_NOT_A_FUNCTION;
-
- node = node->next;
-
- argument = _token_list_create (arguments);
- _argument_list_append (arguments, argument);
-
- for (paren_count = 1; node; node = node->next) {
- if (node->token->type == '(')
- {
- paren_count++;
- }
- else if (node->token->type == ')')
- {
- paren_count--;
- if (paren_count == 0)
- break;
- }
-
- if (node->token->type == ',' &&
- paren_count == 1)
- {
- _token_list_trim_trailing_space (argument);
- argument = _token_list_create (arguments);
- _argument_list_append (arguments, argument);
- }
- else {
- if (argument->head == NULL) {
- /* Don't treat initial whitespace as
- * part of the arguement. */
- if (node->token->type == SPACE)
- continue;
- }
- _token_list_append (argument, node->token);
- }
- }
-
- if (paren_count)
- return FUNCTION_UNBALANCED_PARENTHESES;
-
- *last = node;
-
- return FUNCTION_STATUS_SUCCESS;
-}
-
-/* This is a helper function that's essentially part of the
- * implementation of _glcpp_parser_expand_node. It shouldn't be called
- * except for by that function.
- *
- * Returns NULL if node is a simple token with no expansion, (that is,
- * although 'node' corresponds to an identifier defined as a
- * function-like macro, it is not followed with a parenthesized
- * argument list).
- *
- * Compute the complete expansion of node (which is a function-like
- * macro) and subsequent nodes which are arguments.
- *
- * Returns the token list that results from the expansion and sets
- * *last to the last node in the list that was consumed by the
- * expansion. Specificallty, *last will be set as follows: as the
- * token of the closing right parenthesis.
- */
-static token_list_t *
-_glcpp_parser_expand_function (glcpp_parser_t *parser,
- token_node_t *node,
- token_node_t **last)
-
-{
- macro_t *macro;
- const char *identifier;
- argument_list_t *arguments;
- function_status_t status;
- token_list_t *substituted;
- int parameter_index;
-
- identifier = node->token->value.str;
-
- macro = hash_table_find (parser->defines, identifier);
-
- assert (macro->is_function);
-
- arguments = _argument_list_create (parser);
- status = _arguments_parse (arguments, node, last);
-
- switch (status) {
- case FUNCTION_STATUS_SUCCESS:
- break;
- case FUNCTION_NOT_A_FUNCTION:
- return NULL;
- case FUNCTION_UNBALANCED_PARENTHESES:
- glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier);
- return NULL;
- }
-
- if (macro->replacements == NULL) {
- talloc_free (arguments);
- return _token_list_create (parser);
- }
-
- if (! ((_argument_list_length (arguments) ==
- _string_list_length (macro->parameters)) ||
- (_string_list_length (macro->parameters) == 0 &&
- _argument_list_length (arguments) == 1 &&
- arguments->head->argument->head == NULL)))
- {
- glcpp_error (&node->token->location, parser,
- "Error: macro %s invoked with %d arguments (expected %d)\n",
- identifier,
- _argument_list_length (arguments),
- _string_list_length (macro->parameters));
- return NULL;
- }
-
- /* Perform argument substitution on the replacement list. */
- substituted = _token_list_create (arguments);
-
- for (node = macro->replacements->head; node; node = node->next)
- {
- if (node->token->type == IDENTIFIER &&
- _string_list_contains (macro->parameters,
- node->token->value.str,
- ¶meter_index))
- {
- token_list_t *argument;
- argument = _argument_list_member_at (arguments,
- parameter_index);
- /* Before substituting, we expand the argument
- * tokens, or append a placeholder token for
- * an empty argument. */
- if (argument->head) {
- _glcpp_parser_expand_token_list (parser,
- argument);
- _token_list_append_list (substituted, argument);
- } else {
- token_t *new_token;
-
- new_token = _token_create_ival (substituted,
- PLACEHOLDER,
- PLACEHOLDER);
- _token_list_append (substituted, new_token);
- }
- } else {
- _token_list_append (substituted, node->token);
- }
- }
-
- /* After argument substitution, and before further expansion
- * below, implement token pasting. */
-
- _token_list_trim_trailing_space (substituted);
-
- node = substituted->head;
- while (node)
- {
- token_node_t *next_non_space;
-
- /* Look ahead for a PASTE token, skipping space. */
- next_non_space = node->next;
- while (next_non_space && next_non_space->token->type == SPACE)
- next_non_space = next_non_space->next;
-
- if (next_non_space == NULL)
- break;
-
- if (next_non_space->token->type != PASTE) {
- node = next_non_space;
- continue;
- }
-
- /* Now find the next non-space token after the PASTE. */
- next_non_space = next_non_space->next;
- while (next_non_space && next_non_space->token->type == SPACE)
- next_non_space = next_non_space->next;
-
- if (next_non_space == NULL) {
- yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
- return NULL;
- }
-
- node->token = _token_paste (parser, node->token, next_non_space->token);
- node->next = next_non_space->next;
- if (next_non_space == substituted->tail)
- substituted->tail = node;
-
- node = node->next;
- }
-
- substituted->non_space_tail = substituted->tail;
-
- return substituted;
-}
-
-/* Compute the complete expansion of node, (and subsequent nodes after
- * 'node' in the case that 'node' is a function-like macro and
- * subsequent nodes are arguments).
- *
- * Returns NULL if node is a simple token with no expansion.
- *
- * Otherwise, returns the token list that results from the expansion
- * and sets *last to the last node in the list that was consumed by
- * the expansion. Specificallty, *last will be set as follows:
- *
- * As 'node' in the case of object-like macro expansion.
- *
- * As the token of the closing right parenthesis in the case of
- * function-like macro expansion.
- */
-static token_list_t *
-_glcpp_parser_expand_node (glcpp_parser_t *parser,
- token_node_t *node,
- token_node_t **last)
-{
- token_t *token = node->token;
- const char *identifier;
- macro_t *macro;
-
- /* We only expand identifiers */
- if (token->type != IDENTIFIER) {
- /* We change any COMMA into a COMMA_FINAL to prevent
- * it being mistaken for an argument separator
- * later. */
- if (token->type == ',') {
- token->type = COMMA_FINAL;
- token->value.ival = COMMA_FINAL;
- }
-
- return NULL;
- }
-
- /* Look up this identifier in the hash table. */
- identifier = token->value.str;
- macro = hash_table_find (parser->defines, identifier);
-
- /* Not a macro, so no expansion needed. */
- if (macro == NULL)
- return NULL;
-
- /* Finally, don't expand this macro if we're already actively
- * expanding it, (to avoid infinite recursion). */
- if (_active_list_contains (parser->active, identifier)) {
- /* We change the token type here from IDENTIFIER to
- * OTHER to prevent any future expansion of this
- * unexpanded token. */
- char *str;
- token_list_t *expansion;
- token_t *final;
-
- str = xtalloc_strdup (parser, token->value.str);
- final = _token_create_str (parser, OTHER, str);
- expansion = _token_list_create (parser);
- _token_list_append (expansion, final);
- *last = node;
- return expansion;
- }
-
- if (! macro->is_function)
- {
- *last = node;
-
- if (macro->replacements == NULL)
- return _token_list_create (parser);
-
- return _token_list_copy (parser, macro->replacements);
- }
-
- return _glcpp_parser_expand_function (parser, node, last);
-}
-
-/* Push a new identifier onto the active list, returning the new list.
- *
- * Here, 'marker' is the token node that appears in the list after the
- * expansion of 'identifier'. That is, when the list iterator begins
- * examinging 'marker', then it is time to pop this node from the
- * active stack.
- */
-active_list_t *
-_active_list_push (active_list_t *list,
- const char *identifier,
- token_node_t *marker)
-{
- active_list_t *node;
-
- node = xtalloc (list, active_list_t);
- node->identifier = xtalloc_strdup (node, identifier);
- node->marker = marker;
- node->next = list;
-
- return node;
-}
-
-active_list_t *
-_active_list_pop (active_list_t *list)
-{
- active_list_t *node = list;
-
- if (node == NULL)
- return NULL;
-
- node = list->next;
- talloc_free (list);
-
- return node;
-}
-
-int
-_active_list_contains (active_list_t *list, const char *identifier)
-{
- active_list_t *node;
-
- if (list == NULL)
- return 0;
-
- for (node = list; node; node = node->next)
- if (strcmp (node->identifier, identifier) == 0)
- return 1;
-
- return 0;
-}
-
-/* Walk over the token list replacing nodes with their expansion.
- * Whenever nodes are expanded the walking will walk over the new
- * nodes, continuing to expand as necessary. The results are placed in
- * 'list' itself;
- */
-static void
-_glcpp_parser_expand_token_list (glcpp_parser_t *parser,
- token_list_t *list)
-{
- token_node_t *node_prev;
- token_node_t *node, *last = NULL;
- token_list_t *expansion;
-
- if (list == NULL)
- return;
-
- _token_list_trim_trailing_space (list);
-
- node_prev = NULL;
- node = list->head;
-
- while (node) {
-
- while (parser->active && parser->active->marker == node)
- parser->active = _active_list_pop (parser->active);
-
- /* Find the expansion for node, which will replace all
- * nodes from node to last, inclusive. */
- expansion = _glcpp_parser_expand_node (parser, node, &last);
- if (expansion) {
- token_node_t *n;
-
- for (n = node; n != last->next; n = n->next)
- while (parser->active &&
- parser->active->marker == n)
- {
- parser->active = _active_list_pop (parser->active);
- }
-
- parser->active = _active_list_push (parser->active,
- node->token->value.str,
- last->next);
-
- /* Splice expansion into list, supporting a
- * simple deletion if the expansion is
- * empty. */
- if (expansion->head) {
- if (node_prev)
- node_prev->next = expansion->head;
- else
- list->head = expansion->head;
- expansion->tail->next = last->next;
- if (last == list->tail)
- list->tail = expansion->tail;
- } else {
- if (node_prev)
- node_prev->next = last->next;
- else
- list->head = last->next;
- if (last == list->tail)
- list->tail = NULL;
- }
- } else {
- node_prev = node;
- }
- node = node_prev ? node_prev->next : list->head;
- }
-
- while (parser->active)
- parser->active = _active_list_pop (parser->active);
-
- list->non_space_tail = list->tail;
-}
-
-void
-_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
- token_list_t *list)
-{
- if (list == NULL)
- return;
-
- _glcpp_parser_expand_token_list (parser, list);
-
- _token_list_trim_trailing_space (list);
-
- _token_list_print (parser, list);
-}
-
-void
-_check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
- const char *identifier)
-{
- /* According to the GLSL specification, macro names starting with "__"
- * or "GL_" are reserved for future use. So, don't allow them.
- */
- if (strncmp(identifier, "__", 2) == 0) {
- glcpp_error (loc, parser, "Macro names starting with \"__\" are reserved.\n");
- }
- if (strncmp(identifier, "GL_", 3) == 0) {
- glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n");
- }
-}
-
-void
-_define_object_macro (glcpp_parser_t *parser,
- YYLTYPE *loc,
- const char *identifier,
- token_list_t *replacements)
-{
- macro_t *macro;
-
- _check_for_reserved_macro_name(parser, loc, identifier);
-
- macro = xtalloc (parser, macro_t);
-
- macro->is_function = 0;
- macro->parameters = NULL;
- macro->identifier = talloc_strdup (macro, identifier);
- macro->replacements = talloc_steal (macro, replacements);
-
- hash_table_insert (parser->defines, macro, identifier);
-}
-
-void
-_define_function_macro (glcpp_parser_t *parser,
- YYLTYPE *loc,
- const char *identifier,
- string_list_t *parameters,
- token_list_t *replacements)
-{
- macro_t *macro;
-
- _check_for_reserved_macro_name(parser, loc, identifier);
-
- macro = xtalloc (parser, macro_t);
-
- macro->is_function = 1;
- macro->parameters = talloc_steal (macro, parameters);
- macro->identifier = talloc_strdup (macro, identifier);
- macro->replacements = talloc_steal (macro, replacements);
-
- hash_table_insert (parser->defines, macro, identifier);
-}
-
-static int
-glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
-{
- token_node_t *node;
- int ret;
-
- if (parser->lex_from_list == NULL) {
- ret = glcpp_lex (yylval, yylloc, parser->scanner);
-
- /* XXX: This ugly block of code exists for the sole
- * purpose of converting a NEWLINE token into a SPACE
- * token, but only in the case where we have seen a
- * function-like macro name, but have not yet seen its
- * closing parenthesis.
- *
- * There's perhaps a more compact way to do this with
- * mid-rule actions in the grammar.
- *
- * I'm definitely not pleased with the complexity of
- * this code here.
- */
- if (parser->newline_as_space)
- {
- if (ret == '(') {
- parser->paren_count++;
- } else if (ret == ')') {
- parser->paren_count--;
- if (parser->paren_count == 0)
- parser->newline_as_space = 0;
- } else if (ret == NEWLINE) {
- ret = SPACE;
- } else if (ret != SPACE) {
- if (parser->paren_count == 0)
- parser->newline_as_space = 0;
- }
- }
- else if (parser->in_control_line)
- {
- if (ret == NEWLINE)
- parser->in_control_line = 0;
- }
- else if (ret == HASH_DEFINE_OBJ || ret == HASH_DEFINE_FUNC ||
- ret == HASH_UNDEF || ret == HASH_IF ||
- ret == HASH_IFDEF || ret == HASH_IFNDEF ||
- ret == HASH_ELIF || ret == HASH_ELSE ||
- ret == HASH_ENDIF || ret == HASH)
- {
- parser->in_control_line = 1;
- }
- else if (ret == IDENTIFIER)
- {
- macro_t *macro;
- macro = hash_table_find (parser->defines,
- yylval->str);
- if (macro && macro->is_function) {
- parser->newline_as_space = 1;
- parser->paren_count = 0;
- }
- }
-
- return ret;
- }
-
- node = parser->lex_from_node;
-
- if (node == NULL) {
- talloc_free (parser->lex_from_list);
- parser->lex_from_list = NULL;
- return NEWLINE;
- }
-
- *yylval = node->token->value;
- ret = node->token->type;
-
- parser->lex_from_node = node->next;
-
- return ret;
-}
-
-static void
-glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list)
-{
- token_node_t *node;
-
- assert (parser->lex_from_list == NULL);
-
- /* Copy list, eliminating any space tokens. */
- parser->lex_from_list = _token_list_create (parser);
-
- for (node = list->head; node; node = node->next) {
- if (node->token->type == SPACE)
- continue;
- _token_list_append (parser->lex_from_list, node->token);
- }
-
- talloc_free (list);
-
- parser->lex_from_node = parser->lex_from_list->head;
-
- /* It's possible the list consisted of nothing but whitespace. */
- if (parser->lex_from_node == NULL) {
- talloc_free (parser->lex_from_list);
- parser->lex_from_list = NULL;
- }
-}
-
-static void
-_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
- int condition)
-{
- skip_type_t current = SKIP_NO_SKIP;
- skip_node_t *node;
-
- if (parser->skip_stack)
- current = parser->skip_stack->type;
-
- node = xtalloc (parser, skip_node_t);
- node->loc = *loc;
-
- if (current == SKIP_NO_SKIP) {
- if (condition)
- node->type = SKIP_NO_SKIP;
- else
- node->type = SKIP_TO_ELSE;
- } else {
- node->type = SKIP_TO_ENDIF;
- }
-
- node->next = parser->skip_stack;
- parser->skip_stack = node;
-}
-
-static void
-_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
- const char *type, int condition)
-{
- if (parser->skip_stack == NULL) {
- glcpp_error (loc, parser, "%s without #if\n", type);
- return;
- }
-
- if (parser->skip_stack->type == SKIP_TO_ELSE) {
- if (condition)
- parser->skip_stack->type = SKIP_NO_SKIP;
- } else {
- parser->skip_stack->type = SKIP_TO_ENDIF;
- }
-}
-
-static void
-_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc)
-{
- skip_node_t *node;
-
- if (parser->skip_stack == NULL) {
- glcpp_error (loc, parser, "#endif without #if\n");
- return;
- }
-
- node = parser->skip_stack;
- parser->skip_stack = node->next;
- talloc_free (node);
-}
+++ /dev/null
-/*
- * 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 <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "glcpp.h"
-
-extern int yydebug;
-
-static char *
-load_text_file(void *ctx, const char *file_name)
-{
- char *text = NULL;
- struct stat st;
- ssize_t total_read = 0;
- int fd = file_name == NULL ? STDIN_FILENO : open(file_name, O_RDONLY);
-
- if (fd < 0) {
- return NULL;
- }
-
- if (fstat(fd, & st) == 0) {
- text = (char *) talloc_size(ctx, st.st_size + 1);
- if (text != NULL) {
- do {
- ssize_t bytes = read(fd, text + total_read,
- st.st_size - total_read);
- if (bytes < 0) {
- text = NULL;
- break;
- }
-
- if (bytes == 0) {
- break;
- }
-
- total_read += bytes;
- } while (total_read < st.st_size);
-
- text[total_read] = '\0';
- }
- }
-
- close(fd);
-
- return text;
-}
-
-int
-preprocess(void *talloc_ctx, const char **shader, char **info_log);
-
-int
-main (void)
-{
- void *ctx = talloc(NULL, void*);
- const char *shader = load_text_file(ctx, NULL);
- char *info_log = talloc_strdup(ctx, "");
- int ret = preprocess(ctx, &shader, &info_log);
-
- printf("%s", shader);
- fprintf(stderr, "%s", info_log);
-
- talloc_free(ctx);
-
- return ret;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#ifndef GLCPP_H
-#define GLCPP_H
-
-#include <stdint.h>
-
-#include <talloc.h>
-
-#include "hash_table.h"
-
-#define yyscan_t void*
-
-/* Some data types used for parser values. */
-
-typedef struct string_node {
- const char *str;
- struct string_node *next;
-} string_node_t;
-
-typedef struct string_list {
- string_node_t *head;
- string_node_t *tail;
-} string_list_t;
-
-typedef struct token token_t;
-typedef struct token_list token_list_t;
-
-typedef union YYSTYPE
-{
- intmax_t ival;
- char *str;
- string_list_t *string_list;
- token_t *token;
- token_list_t *token_list;
-} YYSTYPE;
-
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-
-typedef struct YYLTYPE {
- int first_line;
- int first_column;
- int last_line;
- int last_column;
- unsigned source;
-} YYLTYPE;
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-
-struct token {
- int type;
- YYSTYPE value;
- YYLTYPE location;
-};
-
-typedef struct token_node {
- token_t *token;
- struct token_node *next;
-} token_node_t;
-
-struct token_list {
- token_node_t *head;
- token_node_t *tail;
- token_node_t *non_space_tail;
-};
-
-typedef struct argument_node {
- token_list_t *argument;
- struct argument_node *next;
-} argument_node_t;
-
-typedef struct argument_list {
- argument_node_t *head;
- argument_node_t *tail;
-} argument_list_t;
-
-typedef struct glcpp_parser glcpp_parser_t;
-
-typedef enum {
- TOKEN_CLASS_IDENTIFIER,
- TOKEN_CLASS_IDENTIFIER_FINALIZED,
- TOKEN_CLASS_FUNC_MACRO,
- TOKEN_CLASS_OBJ_MACRO
-} token_class_t;
-
-token_class_t
-glcpp_parser_classify_token (glcpp_parser_t *parser,
- const char *identifier,
- int *parameter_index);
-
-typedef struct {
- int is_function;
- string_list_t *parameters;
- const char *identifier;
- token_list_t *replacements;
-} macro_t;
-
-typedef struct expansion_node {
- macro_t *macro;
- token_node_t *replacements;
- struct expansion_node *next;
-} expansion_node_t;
-
-typedef enum skip_type {
- SKIP_NO_SKIP,
- SKIP_TO_ELSE,
- SKIP_TO_ENDIF
-} skip_type_t;
-
-typedef struct skip_node {
- skip_type_t type;
- YYLTYPE loc; /* location of the initial #if/#elif/... */
- struct skip_node *next;
-} skip_node_t;
-
-typedef struct active_list {
- const char *identifier;
- token_node_t *marker;
- struct active_list *next;
-} active_list_t;
-
-struct glcpp_parser {
- yyscan_t scanner;
- struct hash_table *defines;
- active_list_t *active;
- int lexing_if;
- int space_tokens;
- int newline_as_space;
- int in_control_line;
- int paren_count;
- skip_node_t *skip_stack;
- token_list_t *lex_from_list;
- token_node_t *lex_from_node;
- char *output;
- char *info_log;
- int error;
-};
-
-glcpp_parser_t *
-glcpp_parser_create (void);
-
-int
-glcpp_parser_parse (glcpp_parser_t *parser);
-
-void
-glcpp_parser_destroy (glcpp_parser_t *parser);
-
-int
-preprocess(void *talloc_ctx, const char **shader, char **info_log);
-
-/* Functions for writing to the info log */
-
-void
-glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
-
-void
-glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
-
-/* Generated by glcpp-lex.l to glcpp-lex.c */
-
-int
-glcpp_lex_init_extra (glcpp_parser_t *parser, yyscan_t* scanner);
-
-void
-glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader);
-
-int
-glcpp_lex (YYSTYPE *lvalp, YYLTYPE *llocp, yyscan_t scanner);
-
-int
-glcpp_lex_destroy (yyscan_t scanner);
-
-/* Generated by glcpp-parse.y to glcpp-parse.c */
-
-int
-yyparse (glcpp_parser_t *parser);
-
-/* xtalloc - wrappers around talloc to check for out-of-memory */
-
-#define xtalloc(ctx, type) (type *)xtalloc_named_const(ctx, sizeof(type), #type)
-
-#define xtalloc_size(ctx, size) xtalloc_named_const(ctx, size, __location__)
-
-void *
-xtalloc_named_const (const void *context, size_t size, const char *name);
-
-char *
-xtalloc_strdup (const void *t, const char *p);
-
-char *
-xtalloc_strndup (const void *t, const char *p, size_t n);
-
-char *
-xtalloc_asprintf (const void *t, const char *fmt, ...);
-
-void *
-_xtalloc_reference_loc (const void *context,
- const void *ptr, const char *location);
-
-#define xtalloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_xtalloc_reference_loc((ctx),(ptr), __location__)
-
-#endif
+++ /dev/null
-/*
- * Copyright © 2008 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.
- */
-
-/**
- * \file hash_table.c
- * \brief Implementation of a generic, opaque hash table data type.
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#include "main/imports.h"
-#include "main/simple_list.h"
-#include "hash_table.h"
-
-struct node {
- struct node *next;
- struct node *prev;
-};
-
-struct hash_table {
- hash_func_t hash;
- hash_compare_func_t compare;
-
- unsigned num_buckets;
- struct node buckets[1];
-};
-
-
-struct hash_node {
- struct node link;
- const void *key;
- void *data;
-};
-
-
-struct hash_table *
-hash_table_ctor(unsigned num_buckets, hash_func_t hash,
- hash_compare_func_t compare)
-{
- struct hash_table *ht;
- unsigned i;
-
-
- if (num_buckets < 16) {
- num_buckets = 16;
- }
-
- ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1)
- * sizeof(ht->buckets[0])));
- if (ht != NULL) {
- ht->hash = hash;
- ht->compare = compare;
- ht->num_buckets = num_buckets;
-
- for (i = 0; i < num_buckets; i++) {
- make_empty_list(& ht->buckets[i]);
- }
- }
-
- return ht;
-}
-
-
-void
-hash_table_dtor(struct hash_table *ht)
-{
- hash_table_clear(ht);
- _mesa_free(ht);
-}
-
-
-void
-hash_table_clear(struct hash_table *ht)
-{
- struct node *node;
- struct node *temp;
- unsigned i;
-
-
- for (i = 0; i < ht->num_buckets; i++) {
- foreach_s(node, temp, & ht->buckets[i]) {
- remove_from_list(node);
- _mesa_free(node);
- }
-
- assert(is_empty_list(& ht->buckets[i]));
- }
-}
-
-
-void *
-hash_table_find(struct hash_table *ht, const void *key)
-{
- const unsigned hash_value = (*ht->hash)(key);
- const unsigned bucket = hash_value % ht->num_buckets;
- struct node *node;
-
- foreach(node, & ht->buckets[bucket]) {
- struct hash_node *hn = (struct hash_node *) node;
-
- if ((*ht->compare)(hn->key, key) == 0) {
- return hn->data;
- }
- }
-
- return NULL;
-}
-
-
-void
-hash_table_insert(struct hash_table *ht, void *data, const void *key)
-{
- const unsigned hash_value = (*ht->hash)(key);
- const unsigned bucket = hash_value % ht->num_buckets;
- struct hash_node *node;
-
- node = _mesa_calloc(sizeof(*node));
-
- node->data = data;
- node->key = key;
-
- insert_at_head(& ht->buckets[bucket], & node->link);
-}
-
-
-unsigned
-hash_table_string_hash(const void *key)
-{
- const char *str = (const char *) key;
- unsigned hash = 5381;
-
-
- while (*str != '\0') {
- hash = (hash * 33) + *str;
- str++;
- }
-
- return hash;
-}
+++ /dev/null
-/*
- * Copyright © 2008 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.
- */
-
-/**
- * \file hash_table.h
- * \brief Implementation of a generic, opaque hash table data type.
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#ifndef HASH_TABLE_H
-#define HASH_TABLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <string.h>
-
-struct hash_table;
-
-typedef unsigned (*hash_func_t)(const void *key);
-typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
-
-/**
- * Hash table constructor
- *
- * Creates a hash table with the specified number of buckets. The supplied
- * \c hash and \c compare routines are used when adding elements to the table
- * and when searching for elements in the table.
- *
- * \param num_buckets Number of buckets (bins) in the hash table.
- * \param hash Function used to compute hash value of input keys.
- * \param compare Function used to compare keys.
- */
-extern struct hash_table *hash_table_ctor(unsigned num_buckets,
- hash_func_t hash, hash_compare_func_t compare);
-
-
-/**
- * Release all memory associated with a hash table
- *
- * \warning
- * This function cannot release memory occupied either by keys or data.
- */
-extern void hash_table_dtor(struct hash_table *ht);
-
-
-/**
- * Flush all entries from a hash table
- *
- * \param ht Table to be cleared of its entries.
- */
-extern void hash_table_clear(struct hash_table *ht);
-
-
-/**
- * Search a hash table for a specific element
- *
- * \param ht Table to be searched
- * \param key Key of the desired element
- *
- * \return
- * The \c data value supplied to \c hash_table_insert when the element with
- * the matching key was added. If no matching key exists in the table,
- * \c NULL is returned.
- */
-extern void *hash_table_find(struct hash_table *ht, const void *key);
-
-
-/**
- * Add an element to a hash table
- */
-extern void hash_table_insert(struct hash_table *ht, void *data,
- const void *key);
-
-
-/**
- * Compute hash value of a string
- *
- * Computes the hash value of a string using the DJB2 algorithm developed by
- * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
- * a time. I was unable to find the original posting in the archives.
- *
- * \param key Pointer to a NUL terminated string to be hashed.
- *
- * \sa hash_table_string_compare
- */
-extern unsigned hash_table_string_hash(const void *key);
-
-
-/**
- * Compare two strings used as keys
- *
- * This is just a macro wrapper around \c strcmp.
- *
- * \sa hash_table_string_hash
- */
-#define hash_table_string_compare ((hash_compare_func_t) strcmp)
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* HASH_TABLE_H */
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#define _mesa_malloc(x) malloc(x)
-#define _mesa_free(x) free(x)
-#define _mesa_calloc(x) calloc(1,x)
+++ /dev/null
-/**
- * \file simple_list.h
- * Simple macros for type-safe, intrusive lists.
- *
- * Intended to work with a list sentinal which is created as an empty
- * list. Insert & delete are O(1).
- *
- * \author
- * (C) 1997, Keith Whitwell
- */
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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.
- */
-
-
-#ifndef _SIMPLE_LIST_H
-#define _SIMPLE_LIST_H
-
-struct simple_node {
- struct simple_node *next;
- struct simple_node *prev;
-};
-
-/**
- * Remove an element from list.
- *
- * \param elem element to remove.
- */
-#define remove_from_list(elem) \
-do { \
- (elem)->next->prev = (elem)->prev; \
- (elem)->prev->next = (elem)->next; \
-} while (0)
-
-/**
- * Insert an element to the list head.
- *
- * \param list list.
- * \param elem element to insert.
- */
-#define insert_at_head(list, elem) \
-do { \
- (elem)->prev = list; \
- (elem)->next = (list)->next; \
- (list)->next->prev = elem; \
- (list)->next = elem; \
-} while(0)
-
-/**
- * Insert an element to the list tail.
- *
- * \param list list.
- * \param elem element to insert.
- */
-#define insert_at_tail(list, elem) \
-do { \
- (elem)->next = list; \
- (elem)->prev = (list)->prev; \
- (list)->prev->next = elem; \
- (list)->prev = elem; \
-} while(0)
-
-/**
- * Move an element to the list head.
- *
- * \param list list.
- * \param elem element to move.
- */
-#define move_to_head(list, elem) \
-do { \
- remove_from_list(elem); \
- insert_at_head(list, elem); \
-} while (0)
-
-/**
- * Move an element to the list tail.
- *
- * \param list list.
- * \param elem element to move.
- */
-#define move_to_tail(list, elem) \
-do { \
- remove_from_list(elem); \
- insert_at_tail(list, elem); \
-} while (0)
-
-/**
- * Consatinate a cyclic list to a list
- *
- * Appends the sequence of nodes starting with \c tail to the list \c head.
- * A "cyclic list" is a list that does not have a sentinal node. This means
- * that the data pointed to by \c tail is an actual node, not a dataless
- * sentinal. Note that if \c tail constist of a single node, this macro
- * behaves identically to \c insert_at_tail
- *
- * \param head Head of the list to be appended to. This may or may not
- * be a cyclic list.
- * \param tail Head of the cyclic list to be appended to \c head.
- * \param temp Temporary \c simple_list used by the macro
- *
- * \sa insert_at_tail
- */
-#define concat_list_and_cycle(head, tail, temp) \
-do { \
- (head)->prev->next = (tail); \
- (tail)->prev->next = (head); \
- (temp) = (head)->prev; \
- (head)->prev = (tail)->prev; \
- (tail)->prev = (temp); \
-} while (0)
-
-#define concat_list(head, next_list) \
-do { \
- (next_list)->next->prev = (head)->prev; \
- (next_list)->prev->next = (head); \
- (head)->prev->next = (next_list)->next; \
- (head)->prev = (next_list)->prev; \
-} while (0)
-
-/**
- * Make a empty list empty.
- *
- * \param sentinal list (sentinal element).
- */
-#define make_empty_list(sentinal) \
-do { \
- (sentinal)->next = sentinal; \
- (sentinal)->prev = sentinal; \
-} while (0)
-
-/**
- * Get list first element.
- *
- * \param list list.
- *
- * \return pointer to first element.
- */
-#define first_elem(list) ((list)->next)
-
-/**
- * Get list last element.
- *
- * \param list list.
- *
- * \return pointer to last element.
- */
-#define last_elem(list) ((list)->prev)
-
-/**
- * Get next element.
- *
- * \param elem element.
- *
- * \return pointer to next element.
- */
-#define next_elem(elem) ((elem)->next)
-
-/**
- * Get previous element.
- *
- * \param elem element.
- *
- * \return pointer to previous element.
- */
-#define prev_elem(elem) ((elem)->prev)
-
-/**
- * Test whether element is at end of the list.
- *
- * \param list list.
- * \param elem element.
- *
- * \return non-zero if element is at end of list, or zero otherwise.
- */
-#define at_end(list, elem) ((elem) == (list))
-
-/**
- * Test if a list is empty.
- *
- * \param list list.
- *
- * \return non-zero if list empty, or zero otherwise.
- */
-#define is_empty_list(list) ((list)->next == (list))
-
-/**
- * Walk through the elements of a list.
- *
- * \param ptr pointer to the current element.
- * \param list list.
- *
- * \note It should be followed by a { } block or a single statement, as in a \c
- * for loop.
- */
-#define foreach(ptr, list) \
- for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next )
-
-/**
- * Walk through the elements of a list.
- *
- * Same as #foreach but lets you unlink the current value during a list
- * traversal. Useful for freeing a list, element by element.
- *
- * \param ptr pointer to the current element.
- * \param t temporary pointer.
- * \param list list.
- *
- * \note It should be followed by a { } block or a single statement, as in a \c
- * for loop.
- */
-#define foreach_s(ptr, t, list) \
- for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
-
-#endif
+++ /dev/null
-/*
- * 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 <assert.h>
-#include <ctype.h>
-#include "glcpp.h"
-
-void
-glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
-{
- parser->error = 1;
- parser->info_log = talloc_asprintf_append(parser->info_log,
- "%u:%u(%u): "
- "preprocessor error: ",
- locp->source,
- locp->first_line,
- locp->first_column);
- va_list ap;
- va_start(ap, fmt);
- parser->info_log = talloc_vasprintf_append(parser->info_log, fmt, ap);
- va_end(ap);
- parser->info_log = talloc_strdup_append(parser->info_log, "\n");
-}
-
-void
-glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
-{
- parser->info_log = talloc_asprintf_append(parser->info_log,
- "%u:%u(%u): "
- "preprocessor warning: ",
- locp->source,
- locp->first_line,
- locp->first_column);
- va_list ap;
- va_start(ap, fmt);
- parser->info_log = talloc_vasprintf_append(parser->info_log, fmt, ap);
- va_end(ap);
- parser->info_log = talloc_strdup_append(parser->info_log, "\n");
-}
-
-/* Searches backwards for '^ *#' from a given starting point. */
-static int
-in_directive(const char *shader, const char *ptr)
-{
- assert(ptr >= shader);
-
- /* Search backwards for '#'. If we find a \n first, it doesn't count */
- for (; ptr >= shader && *ptr != '#'; ptr--) {
- if (*ptr == '\n')
- return 0;
- }
- if (ptr >= shader) {
- /* Found '#'...look for spaces preceded by a newline */
- for (ptr--; ptr >= shader && isblank(*ptr); ptr--);
- // FIXME: I don't think the '\n' case can happen
- if (ptr < shader || *ptr == '\n')
- return 1;
- }
- return 0;
-}
-
-/* Remove any line continuation characters in preprocessing directives.
- * However, ignore any in GLSL code, as "There is no line continuation
- * character" (1.30 page 9) in GLSL.
- */
-static char *
-remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
-{
- int in_continued_line = 0;
- int extra_newlines = 0;
- char *clean = talloc_strdup(ctx, "");
- const char *search_start = shader;
- const char *newline;
- while ((newline = strchr(search_start, '\n')) != NULL) {
- const char *backslash = NULL;
- /* Find the preceding '\', if it exists */
- if (newline[-1] == '\\') {
- backslash = newline - 1;
- } else if (newline[-1] == '\r' && newline[-2] == '\\') {
- backslash = newline - 2;
- }
- /* Double backslashes don't count (the backslash is escaped) */
- if (backslash != NULL && backslash[-1] == '\\') {
- backslash = NULL;
- }
-
- if (backslash != NULL) {
- /* We found a line continuation, but do we care? */
- if (!in_continued_line) {
- if (in_directive(shader, backslash)) {
- in_continued_line = 1;
- extra_newlines = 0;
- }
- }
- if (in_continued_line) {
- /* Copy everything before the \ */
- clean = talloc_strndup_append(clean, shader, backslash - shader);
- shader = newline + 1;
- extra_newlines++;
- }
- } else if (in_continued_line) {
- /* Copy everything up to and including the \n */
- clean = talloc_strndup_append(clean, shader, newline - shader + 1);
- shader = newline + 1;
- /* Output extra newlines to make line numbers match */
- for (; extra_newlines > 0; extra_newlines--)
- clean = talloc_strdup_append(clean, "\n");
- in_continued_line = 0;
- }
- search_start = newline + 1;
- }
- clean = talloc_strdup_append(clean, shader);
- return clean;
-}
-
-extern int
-preprocess(void *talloc_ctx, const char **shader, char **info_log)
-{
- int errors;
- glcpp_parser_t *parser = glcpp_parser_create ();
- *shader = remove_line_continuations(parser, *shader);
-
- glcpp_lex_set_source_string (parser, *shader);
-
- glcpp_parser_parse (parser);
-
- *info_log = talloc_strdup_append(*info_log, parser->info_log);
-
- talloc_steal(talloc_ctx, parser->output);
- *shader = parser->output;
-
- errors = parser->error;
- glcpp_parser_destroy (parser);
- return errors;
-}
+++ /dev/null
-this is four tokens
+++ /dev/null
-this is four tokens
-
+++ /dev/null
-#define foo 1
-foo
+++ /dev/null
-#define foo 1
-#define bar foo
-bar
+++ /dev/null
-#define bar foo
-#define foo 1
-bar
+++ /dev/null
-#define foo bar
-#define bar baz
-#define baz foo
-foo
-bar
-baz
+++ /dev/null
-
-
-
-foo
-bar
-baz
-
+++ /dev/null
-#define foo 1
-#define bar a foo
-bar
+++ /dev/null
-#define bar a foo
-#define foo 1
-bar
+++ /dev/null
-#define foo a bar
-#define bar b baz
-#define baz c foo
-foo
-bar
-baz
+++ /dev/null
-
-
-
-a b c foo
-b c a bar
-c a b baz
-
+++ /dev/null
-#define foo
-foo
+++ /dev/null
-#define foo 1
-foo
-#undef foo
-foo
+++ /dev/null
-
-1
-
-foo
-
+++ /dev/null
-#define foo 1
-foo
-#undef foo
-foo
-#define foo 2
-foo
+++ /dev/null
-
-1
-
-foo
-
-2
-
+++ /dev/null
-#define foo()
-foo()
+++ /dev/null
-#define foo() bar
-foo()
+++ /dev/null
-#define foo(x) 1
-foo(bar)
+++ /dev/null
-#define foo(x,y) 1
-foo(bar,baz)
+++ /dev/null
-#define foo ()1
-foo()
-#define bar ()2
-bar()
+++ /dev/null
-
-()1()
-
-()2()
-
+++ /dev/null
-#define foo(x) ((x)+1)
-foo(bar)
+++ /dev/null
-
-((bar)+1)
-
+++ /dev/null
-#define foo(x,y) ((x)*(y))
-foo(bar,baz)
+++ /dev/null
-
-((bar)*(baz))
-
+++ /dev/null
-#define x 0
-#define foo(x) x
-foo(1)
+++ /dev/null
-#define foo(x) (x)
-foo(this is more than one word)
+++ /dev/null
-
-(this is more than one word)
-
+++ /dev/null
-#define foo(x,y) x,two fish,red fish,y
-foo(one fish, blue fish)
+++ /dev/null
-
-one fish,two fish,red fish,blue fish
-
+++ /dev/null
-#define bar(x) (1+(x))
-#define foo(y) (2*(y))
-foo(bar(3))
+++ /dev/null
-
-
-(2*((1+(3))))
-
+++ /dev/null
-#define foo(x) (x)
-foo(argument(including parens)for the win)
+++ /dev/null
-
-(argument(including parens)for the win)
-
+++ /dev/null
-#define noargs() 1
-# define onearg(foo) foo
- # define twoargs( x , y ) x y
- # define threeargs( a , b , c ) a b c
-noargs ( )
-onearg ( 2 )
-twoargs ( 3 , 4 )
-threeargs ( 5 , 6 , 7 )
+++ /dev/null
-
-
-
-
-1
-2
-3 4
-5 6 7
-
+++ /dev/null
-#define foo foo
-#define bar foo
-bar
+++ /dev/null
-#define foo(bar) bar
-foo bar
+++ /dev/null
-
-foo bar
-
+++ /dev/null
-#define foo(a) bar
-
-foo
-(
-1
-)
+++ /dev/null
-#define failure() success
-#define foo failure()
-foo
+++ /dev/null
-
-
-success
-
+++ /dev/null
-#define success() failure
-#define foo success
-foo
+++ /dev/null
-
-
-success
-
+++ /dev/null
-#define bar(failure) failure
-#define foo bar(success)
-foo
+++ /dev/null
-
-
-success
-
+++ /dev/null
-#define baz(failure) failure
-#define bar(failure) failure
-#define foo bar(baz(success))
-foo
+++ /dev/null
-
-
-
-success
-
+++ /dev/null
-#define baz(failure) failure
-#define bar(failure) failure
-#define foo() bar(baz(success))
-foo()
+++ /dev/null
-
-
-
-success
-
+++ /dev/null
-#define foo(a) foo(2*(a))
-foo(3)
+++ /dev/null
-
-foo(2*(3))
-
+++ /dev/null
-#define foo(a) foo(2*(a))
-foo(foo(3))
+++ /dev/null
-
-foo(2*(foo(2*(3))))
-
+++ /dev/null
-#define foo(bar) bar
-foo(foo)
+++ /dev/null
-#define foo(bar) bar
-foo(1+foo)
+++ /dev/null
-#define bar success
-#define foo(x) x
-foo(more bar)
+++ /dev/null
-
-
-more success
-
+++ /dev/null
-#define expand(x) expand(x once)
-#define foo(x) x
-foo(expand(just))
+++ /dev/null
-
-
-expand(just once)
-
+++ /dev/null
-#define foo(x) success
-foo(argument (with,embedded , commas) -- tricky)
+++ /dev/null
-
-success
-
+++ /dev/null
-#define foo(a) (a)
-#define bar two,words
-foo(bar)
+++ /dev/null
-
-
-(two,words)
-
+++ /dev/null
-#define paste(a,b) a ## b
-paste(one , token)
+++ /dev/null
-
-onetoken
-
+++ /dev/null
-success_1
-#if 0
-failure
-#endif
-success_2
+++ /dev/null
-success_1
-
-
-
-success_2
-
+++ /dev/null
-success_1
-#if 1
-success_2
-#endif
-success_3
+++ /dev/null
-success_1
-
-success_2
-
-success_3
-
+++ /dev/null
-success_1
-#if 0
-failure
-#else
-success_2
-#endif
-success_3
+++ /dev/null
-success_1
-
-
-
-success_2
-
-success_3
-
+++ /dev/null
-success_1
-#if 1
-success_2
-#else
-failure
-#endif
-success_3
+++ /dev/null
-success_1
-
-success_2
-
-
-
-success_3
-
+++ /dev/null
-success_1
-#if 0
-failure_1
-#elif 0
-failure_2
-#elif 1
-success_3
-#elif 1
-failure_3
-#endif
-success_4
+++ /dev/null
-success_1
-
-
-
-
-
-success_3
-
-
-
-success_4
-
+++ /dev/null
-success_1
-#if 1
-success_2
-#elif 0
-failure_1
-#elif 1
-failure_2
-#elif 0
-failure_3
-#endif
-success_3
+++ /dev/null
-success_1
-
-success_2
-
-
-
-
-
-
-
-success_3
-
+++ /dev/null
-success_1
-#if 0
-failure_1
-#elif 0
-failure_2
-#elif 0
-failure_3
-#else
-success_2
-#endif
-success_3
+++ /dev/null
-success_1
-
-
-
-
-
-
-
-success_2
-
-success_3
-
+++ /dev/null
-success_1
-#if 0
-failure_1
-#if 1
-failure_2
-#else
-failure_3
-#endif
-failure_4
-#endif
-success_2
+++ /dev/null
-success_1
-
-
-
-
-
-
-
-
-
-success_2
-
+++ /dev/null
-#if 1 + 2 * 3 + - (25 % 17 - + 1)
-failure with operator precedence
-#else
-success
-#endif
+++ /dev/null
-
-
-
-success
-
-
+++ /dev/null
-#if defined foo
-failure_1
-#else
-success_1
-#endif
-#define foo
-#if defined foo
-success_2
-#else
-failure_2
-#endif
-#undef foo
-#if defined foo
-failure_3
-#else
-success_3
-#endif
+++ /dev/null
-
-
-
-success_1
-
-
-
-success_2
-
-
-
-
-
-
-
-success_3
-
-
+++ /dev/null
-#if 3 < 2
-failure_1
-#else
-success_1
-#endif
-
-#if 3 >= 2
-success_2
-#else
-failure_2
-#endif
-
-#if 2 + 3 <= 5
-success_3
-#else
-failure_3
-#endif
-
-#if 3 - 2 == 1
-success_3
-#else
-failure_3
-#endif
-
-#if 1 > 3
-failure_4
-#else
-success_4
-#endif
-
-#if 1 != 5
-success_5
-#else
-failure_5
-#endif
+++ /dev/null
-
-
-
-success_1
-
-
-
-success_2
-
-
-
-
-
-success_3
-
-
-
-
-
-success_3
-
-
-
-
-
-
-
-success_4
-
-
-
-success_5
-
-
-
-
+++ /dev/null
-#if (0xaaaaaaaa | 0x55555555) != 4294967295
-failure_1
-#else
-success_1
-#endif
-#if (0x12345678 ^ 0xfdecba98) == 4023971040
-success_2
-#else
-failure_2
-#endif
-#if (~ 0xdeadbeef) != -3735928560
-failure_3
-#else
-success_3
-#endif
-#if (0667 & 0733) == 403
-success_4
-#else
-failure_4
-#endif
+++ /dev/null
-
-
-
-success_1
-
-
-success_2
-
-
-
-
-
-
-success_3
-
-
-success_4
-
-
-
-
+++ /dev/null
-#if (15 / 2) != 7
-failure_1
-#else
-success_1
-#endif
-#if (1 << 12) == 4096
-success_2
-#else
-failure_2
-#endif
-#if (31762 >> 8) != 124
-failure_3
-#else
-success_3
-#endif
+++ /dev/null
-
-
-
-success_1
-
-
-success_2
-
-
-
-
-
-
-success_3
-
-
+++ /dev/null
-#define one 1
-#define two 2
-#define three 3
-#define five 5
-#if five < two
-failure_1
-#else
-success_1
-#endif
-#if three >= two
-success_2
-#else
-failure_2
-#endif
-#if two + three <= five
-success_3
-#else
-failure_3
-#endif
-#if five - two == three
-success_4
-#else
-failure_4
-#endif
-#if one > three
-failure_5
-#else
-success_5
-#endif
-#if one != five
-success_6
-#else
-failure_6
-#endif
+++ /dev/null
-
-
-
-
-
-
-
-success_1
-
-
-success_2
-
-
-
-
-success_3
-
-
-
-
-success_4
-
-
-
-
-
-
-success_5
-
-
-success_6
-
-
-
-
+++ /dev/null
-#define failure() success
-#define foo failure
-foo()
+++ /dev/null
-
-
-success
-
+++ /dev/null
-#define bar with,embedded,commas
-#define function(x) success
-#define foo function
-foo(bar)
+++ /dev/null
-
-
-
-success
-
+++ /dev/null
-#define zero() success
-zero()
-#define one(x) success
-one()
-#define two(x,y) success
-two(,)
+++ /dev/null
-
-success
-
-success
-
-success
-
+++ /dev/null
-#define paste(x,y) x ## y
-paste(a,b)
-paste(a,)
-paste(,b)
-paste(,)
+++ /dev/null
-
-ab
-a
-b
-
-
+++ /dev/null
-#define paste(x,y) x ## y
-paste(1,2)
-paste(1,000)
-paste(identifier,2)
+++ /dev/null
-
-12
-1000
-identifier2
-
+++ /dev/null
-#define double(a) a*2
-#define foo double(
-foo 5)
+++ /dev/null
-#define foo(x) success
-#define bar foo
-#define baz bar
-#define joe baz
-joe (failure)
+++ /dev/null
-
-
-
-
-success
-
+++ /dev/null
-#define foo(a,b)
-#if 0
-foo(bar)
-foo(
-#endif
+++ /dev/null
-
-
-
-
-
-
+++ /dev/null
-/* this is a comment */
-// so is this
-// */
-f = g/**//h;
-/*//*/l();
-m = n//**/o
-+ p;
-/* this
-comment spans
-multiple lines and
-contains *** stars
-and slashes / *** /
-and other stuff.
-****/
-more code here
-/* Test that /* nested
- comments */
-are not treated like comments.
-/*/ this is a comment */
-/*/*/
+++ /dev/null
-
-
-
-f = g /h;
- l();
-m = n
-+ p;
-
-more code here
-
-are not treated like comments.
-
-
-
+++ /dev/null
-#version 130
-#define FOO
+++ /dev/null
-#version 130
-
-
+++ /dev/null
-#if defined(foo)
-failure_1
-#else
-success_1
-#endif
-#define foo
-#if defined ( foo )
-success_2
-#else
-failure_2
-#endif
-#undef foo
-#if defined (foo)
-failure_3
-#else
-success_3
-#endif
+++ /dev/null
-
-
-
-success_1
-
-
-
-success_2
-
-
-
-
-
-
-
-success_3
-
-
+++ /dev/null
-#define paste(x) success_ ## x
-paste(1) paste(2) paste(3)
+++ /dev/null
-
-success_1 success_2 success_3
-
+++ /dev/null
-#define x 3
-#define f(a) f(x * (a))
-#undef x
-#define x 2
-#define g f
-#define z z[0]
-#define h g(~
-#define m(a) a(w)
-#define w 0,1
-#define t(a) a
-#define p() int
-#define q(x) x
-#define r(x,y) x ## y
-f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
-g(x +(3,4)-w) | h 5) & m
- (f)^m(m);
-p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,)};
+++ /dev/null
-
-
-
-
-
-
-
-
-
-
-
-
-
-f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
-f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
-int i[] = { 1, 23, 4, 5, };
-
+++ /dev/null
-#!/bin/sh
-
-for test in *.c; do
- echo "Testing $test"
- ../glcpp < $test > $test.out
- diff -u $test.expected $test.out
-done
+++ /dev/null
-/*
- * 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 <talloc.h>
-
-void *
-xtalloc_named_const (const void *context, size_t size, const char *name)
-{
- void *ret;
-
- ret = talloc_named_const (context, size, name);
- if (ret == NULL) {
- fprintf (stderr, "Out of memory.\n");
- exit (1);
- }
-
- return ret;
-}
-
-char *
-xtalloc_strdup (const void *t, const char *p)
-{
- char *ret;
-
- ret = talloc_strdup (t, p);
- if (ret == NULL) {
- fprintf (stderr, "Out of memory.\n");
- exit (1);
- }
-
- return ret;
-}
-
-char *
-xtalloc_strndup (const void *t, const char *p, size_t n)
-{
- char *ret;
-
- ret = talloc_strndup (t, p, n);
- if (ret == NULL) {
- fprintf (stderr, "Out of memory.\n");
- exit (1);
- }
-
- return ret;
-}
-
-char *
-xtalloc_asprintf (const void *t, const char *fmt, ...)
-{
- va_list ap;
- char *ret;
-
- va_start(ap, fmt);
-
- ret = talloc_vasprintf(t, fmt, ap);
- if (ret == NULL) {
- fprintf (stderr, "Out of memory.\n");
- exit (1);
- }
-
- va_end(ap);
- return ret;
-}
-
-void *
-_xtalloc_reference_loc (const void *context,
- const void *ptr, const char *location)
-{
- void *ret;
-
- ret = _talloc_reference_loc (context, ptr, location);
- if (ret == NULL) {
- fprintf (stderr, "Out of memory.\n");
- exit (1);
- }
-
- return ret;
-}
+++ /dev/null
-%{
-/*
- * 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 <ctype.h>
-#include "ast.h"
-#include "glsl_parser_extras.h"
-#include "glsl_parser.h"
-
-#define YY_USER_ACTION \
- do { \
- yylloc->source = 0; \
- yylloc->first_column = yycolumn + 1; \
- yylloc->first_line = yylineno + 1; \
- yycolumn += yyleng; \
- } while(0);
-
-%}
-
-%option bison-bridge bison-locations reentrant noyywrap
-%option nounput noyy_top_state
-%option never-interactive
-%option prefix="_mesa_glsl_"
-%option extra-type="struct _mesa_glsl_parse_state *"
-
-%x PP
-
-DEC_INT [1-9][0-9]*
-HEX_INT 0[xX][0-9a-fA-F]+
-OCT_INT 0[0-7]*
-INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
-SPC [ \t]*
-SPCP [ \t]+
-HASH ^{SPC}#{SPC}
-%%
-
-[ \r\t]+ ;
-
- /* Preprocessor tokens. */
-^[ \t]*#[ \t]*$ ;
-^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
-^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
-{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
- yylloc->source = strtol(ptr, NULL, 0);
- }
-{HASH}line{SPCP}{INT}{SPC}$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
- }
-^[ \t]*#[ \t]*pragma { BEGIN PP; return PRAGMA; }
-<PP>\/\/[^\n]* { }
-<PP>[ \t\r]* { }
-<PP>: return COLON;
-<PP>[_a-zA-Z][_a-zA-Z0-9]* {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
-<PP>[1-9][0-9]* {
- yylval->n = strtol(yytext, NULL, 10);
- return INTCONSTANT;
- }
-<PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
-
-\n { yylineno++; yycolumn = 0; }
-
-attribute return ATTRIBUTE;
-const return CONST;
-bool return BOOL;
-float return FLOAT;
-int return INT;
-
-break return BREAK;
-continue return CONTINUE;
-do return DO;
-while return WHILE;
-else return ELSE;
-for return FOR;
-if return IF;
-discard return DISCARD;
-return return RETURN;
-
-bvec2 return BVEC2;
-bvec3 return BVEC3;
-bvec4 return BVEC4;
-ivec2 return IVEC2;
-ivec3 return IVEC3;
-ivec4 return IVEC4;
-vec2 return VEC2;
-vec3 return VEC3;
-vec4 return VEC4;
-mat2 return MAT2;
-mat3 return MAT3;
-mat4 return MAT4;
-mat2x2 return MAT2X2;
-mat2x3 return MAT2X3;
-mat2x4 return MAT2X4;
-mat3x2 return MAT3X2;
-mat3x3 return MAT3X3;
-mat3x4 return MAT3X4;
-mat4x2 return MAT4X2;
-mat4x3 return MAT4X3;
-mat4x4 return MAT4X4;
-
-in return IN;
-out return OUT;
-inout return INOUT;
-uniform return UNIFORM;
-varying return VARYING;
-centroid {
- if (yyextra->language_version >= 120) {
- return CENTROID;
- } else {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
- }
-invariant {
- if (yyextra->language_version >= 120) {
- return INVARIANT;
- } else {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
- }
-
-flat {
- if (yyextra->language_version >= 130) {
- return FLAT;
- } else {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
- }
-smooth {
- if (yyextra->language_version >= 130) {
- return SMOOTH;
- } else {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
- }
-noperspective {
- if (yyextra->language_version >= 130) {
- return NOPERSPECTIVE;
- } else {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
- }
-
-sampler1D return SAMPLER1D;
-sampler2D return SAMPLER2D;
-sampler3D return SAMPLER3D;
-samplerCube return SAMPLERCUBE;
-sampler1DShadow return SAMPLER1DSHADOW;
-sampler2DShadow return SAMPLER2DSHADOW;
-
-struct return STRUCT;
-void return VOID;
-
-\+\+ return INC_OP;
--- return DEC_OP;
-\<= return LE_OP;
->= return GE_OP;
-== return EQ_OP;
-!= return NE_OP;
-&& return AND_OP;
-\|\| return OR_OP;
-"^^" return XOR_OP;
-
-\*= return MUL_ASSIGN;
-\/= return DIV_ASSIGN;
-\+= return ADD_ASSIGN;
-\%= return MOD_ASSIGN;
-\<\<= return LEFT_ASSIGN;
->>= return RIGHT_ASSIGN;
-&= return AND_ASSIGN;
-^= return XOR_ASSIGN;
-\|= return OR_ASSIGN;
--= return SUB_ASSIGN;
-
-[1-9][0-9]* {
- yylval->n = strtol(yytext, NULL, 10);
- return INTCONSTANT;
- }
-0[xX][0-9a-fA-F]+ {
- yylval->n = strtol(yytext + 2, NULL, 16);
- return INTCONSTANT;
- }
-0[0-7]* {
- yylval->n = strtol(yytext + 2, NULL, 8);
- return INTCONSTANT;
- }
-
-[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-[0-9]+[eE][+-]?[0-9]+[fF]? {
- yylval->real = strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-
-true {
- yylval->n = 1;
- return BOOLCONSTANT;
- }
-false {
- yylval->n = 0;
- return BOOLCONSTANT;
- }
-
-
- /* Reserved words in GLSL 1.10. */
-asm return ASM;
-class return CLASS;
-union return UNION;
-enum return ENUM;
-typedef return TYPEDEF;
-template return TEMPLATE;
-this return THIS;
-packed return PACKED;
-goto return GOTO;
-switch return SWITCH;
-default return DEFAULT;
-inline return INLINE;
-noinline return NOINLINE;
-volatile return VOLATILE;
-public return PUBLIC;
-static return STATIC;
-extern return EXTERN;
-external return EXTERNAL;
-interface return INTERFACE;
-long return LONG;
-short return SHORT;
-double return DOUBLE;
-half return HALF;
-fixed return FIXED;
-unsigned return UNSIGNED;
-input return INPUT;
-output return OUTPUT;
-hvec2 return HVEC2;
-hvec3 return HVEC3;
-hvec4 return HVEC4;
-dvec2 return DVEC2;
-dvec3 return DVEC3;
-dvec4 return DVEC4;
-fvec2 return FVEC2;
-fvec3 return FVEC3;
-fvec4 return FVEC4;
-sampler2DRect return SAMPLER2DRECT;
-sampler3DRect return SAMPLER3DRECT;
-sampler2DRectShadow return SAMPLER2DRECTSHADOW;
-sizeof return SIZEOF;
-cast return CAST;
-namespace return NAMESPACE;
-using return USING;
-
- /* Additional reserved words in GLSL 1.20. */
-lowp return LOWP;
-mediump return MEDIUMP;
-highp return HIGHP;
-precision return PRECISION;
-
-[_a-zA-Z][_a-zA-Z0-9]* {
- struct _mesa_glsl_parse_state *state = yyextra;
- void *ctx = talloc_parent(state);
- yylval->identifier = talloc_strdup(ctx, yytext);
- return IDENTIFIER;
- }
-
-. { return yytext[0]; }
-
-%%
-
-void
-_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
-{
- yylex_init_extra(state, & state->scanner);
- yy_scan_string(string, state->scanner);
-}
-
-void
-_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
-{
- yylex_destroy(state->scanner);
-}
+++ /dev/null
-%{
-/*
- * 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
-%locations
-%error-verbose
-
-%lex-param {void *scanner}
-%parse-param {struct _mesa_glsl_parse_state *state}
-%name-prefix "_mesa_glsl_"
-
-%union {
- int n;
- float real;
- char *identifier;
-
- union {
- struct ast_type_qualifier q;
- unsigned i;
- } type_qualifier;
-
- struct ast_node *node;
- struct ast_type_specifier *type_specifier;
- struct ast_fully_specified_type *fully_specified_type;
- struct ast_function *function;
- struct ast_parameter_declarator *parameter_declarator;
- struct ast_function_definition *function_definition;
- struct ast_compound_statement *compound_statement;
- struct ast_expression *expression;
- struct ast_declarator_list *declarator_list;
- struct ast_struct_specifier *struct_specifier;
- struct ast_declaration *declaration;
-
- struct {
- struct ast_node *cond;
- struct ast_expression *rest;
- } for_rest_statement;
-}
-
-%token ATTRIBUTE CONST BOOL FLOAT INT UINT
-%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 MAT2 MAT3 MAT4 CENTROID IN OUT INOUT 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 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 PRECISION
-
-%token VERSION EXTENSION LINE PRAGMA COLON EOL INTERFACE OUTPUT
-
- /* Reserved words that are not actually used in the grammar.
- */
-%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED GOTO
-%token INLINE NOINLINE VOLATILE PUBLIC STATIC EXTERN EXTERNAL
-%token LONG SHORT DOUBLE HALF FIXED UNSIGNED INPUT OUPTUT
-%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
-%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW
-%token SIZEOF CAST NAMESPACE USING
-
-%type <identifier> variable_identifier
-%type <node> statement
-%type <node> statement_list
-%type <node> simple_statement
-%type <node> statement_matched
-%type <node> statement_unmatched
-%type <n> precision_qualifier
-%type <type_qualifier> type_qualifier
-%type <type_qualifier> storage_qualifier
-%type <type_qualifier> interpolation_qualifier
-%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_matched
-%type <node> selection_statement_unmatched
-%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 */
- {
- state->language_version = 110;
- }
- | VERSION INTCONSTANT EOL
- {
- switch ($2) {
- case 110:
- case 120:
- case 130:
- /* FINISHME: Check against implementation support versions. */
- state->language_version = $2;
- break;
- default:
- _mesa_glsl_error(& @2, state, "Shading language version"
- "%u is not supported\n", $2);
- break;
- }
- }
- ;
-
-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 = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.identifier = $1;
- }
- | INTCONSTANT
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.int_constant = $1;
- }
- | UINTCONSTANT
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.uint_constant = $1;
- }
- | FLOATCONSTANT
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.float_constant = $1;
- }
- | BOOLCONSTANT
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL);
- $$->set_location(yylloc);
- }
- | function_call
- {
- /* Function call parameters used to be stored as a circular list in
- * subexpressions[1]. They are now stored as a regular list in
- * expressions. This assertion validates that the old code was
- * correctly converted. It can eventually be removed.
- */
- assert($1->subexpressions[1] == NULL);
- $$ = $1;
- }
- | postfix_expression '.' IDENTIFIER
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL);
- $$->set_location(yylloc);
- $$->primary_expression.identifier = $3;
- }
- | postfix_expression INC_OP
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL);
- $$->set_location(yylloc);
- }
- | postfix_expression DEC_OP
- {
- void *ctx = talloc_parent(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 = talloc_parent(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
- | 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 = talloc_parent(state);
- $$ = new(ctx) ast_function_expression($1);
- $$->set_location(yylloc);
- }
- | IDENTIFIER
- {
- void *ctx = talloc_parent(state);
- ast_expression *callee = new(ctx) ast_expression($1);
- $$ = new(ctx) ast_function_expression(callee);
- $$->set_location(yylloc);
- }
- | FIELD_SELECTION
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL);
- $$->set_location(yylloc);
- }
- | DEC_OP unary_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL);
- $$->set_location(yylloc);
- }
- | unary_operator unary_expression
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3);
- $$->set_location(yylloc);
- }
- | multiplicative_expression '/' unary_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_div, $1, $3);
- $$->set_location(yylloc);
- }
- | multiplicative_expression '%' unary_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-additive_expression:
- multiplicative_expression
- | additive_expression '+' multiplicative_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_add, $1, $3);
- $$->set_location(yylloc);
- }
- | additive_expression '-' multiplicative_expression
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3);
- $$->set_location(yylloc);
- }
- | shift_expression RIGHT_OP additive_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-relational_expression:
- shift_expression
- | relational_expression '<' shift_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_less, $1, $3);
- $$->set_location(yylloc);
- }
- | relational_expression '>' shift_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3);
- $$->set_location(yylloc);
- }
- | relational_expression LE_OP shift_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3);
- $$->set_location(yylloc);
- }
- | relational_expression GE_OP shift_expression
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3);
- $$->set_location(yylloc);
- }
- | equality_expression NE_OP relational_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-and_expression:
- equality_expression
- | and_expression '&' equality_expression
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3);
- $$->set_location(yylloc);
- }
- ;
-
-exclusive_or_expression:
- and_expression
- | exclusive_or_expression '^' and_expression
- {
- void *ctx = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_function();
- $$->set_location(yylloc);
- $$->return_type = $1;
- $$->identifier = $2;
- }
- ;
-
-parameter_declarator:
- type_specifier IDENTIFIER
- {
- void *ctx = talloc_parent(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 = talloc_parent(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.i |= $2.i;
-
- $$ = $3;
- $$->type->qualifier = $1.q;
- }
- | parameter_qualifier parameter_declarator
- {
- $$ = $2;
- $$->type->qualifier = $1.q;
- }
- | parameter_type_qualifier parameter_qualifier parameter_type_specifier
- {
- void *ctx = talloc_parent(state);
- $1.i |= $2.i;
-
- $$ = new(ctx) ast_parameter_declarator();
- $$->set_location(yylloc);
- $$->type = new(ctx) ast_fully_specified_type();
- $$->type->qualifier = $1.q;
- $$->type->specifier = $3;
- }
- | parameter_qualifier parameter_type_specifier
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_parameter_declarator();
- $$->set_location(yylloc);
- $$->type = new(ctx) ast_fully_specified_type();
- $$->type->qualifier = $1.q;
- $$->type->specifier = $2;
- }
- ;
-
-parameter_qualifier:
- /* empty */ { $$.i = 0; }
- | IN { $$.i = 0; $$.q.in = 1; }
- | OUT { $$.i = 0; $$.q.out = 1; }
- | INOUT { $$.i = 0; $$.q.in = 1; $$.q.out = 1; }
- ;
-
-parameter_type_specifier:
- type_specifier
- ;
-
-init_declarator_list:
- single_declaration
- | init_declarator_list ',' IDENTIFIER
- {
- void *ctx = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_fully_specified_type();
- $$->set_location(yylloc);
- $$->specifier = $1;
- }
- | type_qualifier type_specifier
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_fully_specified_type();
- $$->set_location(yylloc);
- $$->qualifier = $1.q;
- $$->specifier = $2;
- }
- ;
-
-interpolation_qualifier:
- SMOOTH { $$.i = 0; $$.q.smooth = 1; }
- | FLAT { $$.i = 0; $$.q.flat = 1; }
- | NOPERSPECTIVE { $$.i = 0; $$.q.noperspective = 1; }
- ;
-
-parameter_type_qualifier:
- CONST { $$.i = 0; $$.q.constant = 1; }
- ;
-
-type_qualifier:
- storage_qualifier
- | interpolation_qualifier type_qualifier
- {
- $$.i = $1.i | $2.i;
- }
- | INVARIANT type_qualifier
- {
- $$ = $2;
- $$.q.invariant = 1;
- }
- ;
-
-storage_qualifier:
- CONST { $$.i = 0; $$.q.constant = 1; }
- | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; }
- | VARYING { $$.i = 0; $$.q.varying = 1; }
- | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; }
- | IN { $$.i = 0; $$.q.in = 1; }
- | OUT { $$.i = 0; $$.q.out = 1; }
- | CENTROID IN { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; }
- | CENTROID OUT { $$.i = 0; $$.q.centroid = 1; $$.q.out = 1; }
- | UNIFORM { $$.i = 0; $$.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 = talloc_parent(state);
- $$ = new(ctx) ast_type_specifier($1);
- $$->set_location(yylloc);
- }
- | struct_specifier
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_type_specifier($1);
- $$->set_location(yylloc);
- }
- | IDENTIFIER
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_type_specifier($1);
- $$->set_location(yylloc);
- }
- ;
-
-basic_type_specifier_nonarray:
- VOID { $$ = ast_void; }
- | FLOAT { $$ = ast_float; }
- | INT { $$ = ast_int; }
- | UINT { $$ = ast_uint; }
- | BOOL { $$ = 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; }
- | MAT2 { $$ = ast_mat2; }
- | MAT3 { $$ = ast_mat3; }
- | MAT4 { $$ = ast_mat4; }
- | 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->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precission qualifier forbidden "
- "in GLSL %d.%d (1.30 or later "
- "required)\n",
- state->language_version / 100,
- state->language_version % 100);
-
- $$ = ast_precision_high;
- }
- | MEDIUMP {
- if (state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precission qualifier forbidden "
- "in GLSL %d.%d (1.30 or later "
- "required)\n",
- state->language_version / 100,
- state->language_version % 100);
-
- $$ = ast_precision_medium;
- }
- | LOWP {
- if (state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precission qualifier forbidden "
- "in GLSL %d.%d (1.30 or later "
- "required)\n",
- state->language_version / 100,
- state->language_version % 100);
-
- $$ = ast_precision_low;
- }
- ;
-
-struct_specifier:
- STRUCT IDENTIFIER '{' struct_declaration_list '}'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_struct_specifier($2, $4);
- $$->set_location(yylloc);
- }
- | STRUCT '{' struct_declaration_list '}'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_struct_specifier(NULL, $3);
- $$->set_location(yylloc);
- }
- ;
-
-struct_declaration_list:
- struct_declaration
- {
- $$ = (struct ast_node *) $1;
- $1->link.self_link();
- }
- | struct_declaration_list struct_declaration
- {
- $$ = (struct ast_node *) $1;
- $$->link.insert_before(& $2->link);
- }
- ;
-
-struct_declaration:
- type_specifier struct_declarator_list ';'
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_declaration($1, false, NULL, NULL);
- $$->set_location(yylloc);
- }
- | IDENTIFIER '[' constant_expression ']'
- {
- void *ctx = talloc_parent(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:
- statement_matched
- | statement_unmatched
- ;
-
-statement_matched:
- compound_statement { $$ = (struct ast_node *) $1; }
- | simple_statement
- ;
-
-statement_unmatched:
- selection_statement_unmatched
- ;
-
-simple_statement:
- declaration_statement
- | expression_statement
- | selection_statement_matched
- | switch_statement { $$ = NULL; }
- | case_label { $$ = NULL; }
- | iteration_statement
- | jump_statement
- ;
-
-compound_statement:
- '{' '}'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_compound_statement(true, NULL);
- $$->set_location(yylloc);
- }
- | '{' statement_list '}'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_compound_statement(true, $2);
- $$->set_location(yylloc);
- }
- ;
-
-statement_no_new_scope:
- compound_statement_no_new_scope { $$ = (struct ast_node *) $1; }
- | simple_statement
- ;
-
-compound_statement_no_new_scope:
- '{' '}'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_compound_statement(false, NULL);
- $$->set_location(yylloc);
- }
- | '{' statement_list '}'
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_expression_statement(NULL);
- $$->set_location(yylloc);
- }
- | expression ';'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_expression_statement($1);
- $$->set_location(yylloc);
- }
- ;
-
-selection_statement_matched:
- IF '(' expression ')' statement_matched ELSE statement_matched
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_selection_statement($3, $5, $7);
- $$->set_location(yylloc);
- }
- ;
-
-selection_statement_unmatched:
- IF '(' expression ')' statement_matched
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_selection_statement($3, $5, NULL);
- $$->set_location(yylloc);
- }
- | IF '(' expression ')' statement_unmatched
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_selection_statement($3, $5, NULL);
- $$->set_location(yylloc);
- }
- | IF '(' expression ')' statement_matched ELSE statement_unmatched
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_selection_statement($3, $5, $7);
- $$->set_location(yylloc);
- }
- ;
-
-condition:
- expression
- {
- $$ = (struct ast_node *) $1;
- }
- | fully_specified_type IDENTIFIER '=' initializer
- {
- void *ctx = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while,
- NULL, $3, NULL, $5);
- $$->set_location(yylloc);
- }
- | DO statement WHILE '(' expression ')' ';'
- {
- void *ctx = talloc_parent(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 = talloc_parent(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 = talloc_parent(state);
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL);
- $$->set_location(yylloc);
- }
- | BREAK ';'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL);
- $$->set_location(yylloc);
- }
- | RETURN ';'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL);
- $$->set_location(yylloc);
- }
- | RETURN expression ';'
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2);
- $$->set_location(yylloc);
- }
- | DISCARD ';' // Fragment shader only.
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL);
- $$->set_location(yylloc);
- }
- ;
-
-external_declaration:
- function_definition { $$ = $1; }
- | declaration { $$ = $1; }
- ;
-
-function_definition:
- function_prototype compound_statement_no_new_scope
- {
- void *ctx = talloc_parent(state);
- $$ = new(ctx) ast_function_definition();
- $$->set_location(yylloc);
- $$->prototype = $1;
- $$->body = $2;
- }
- ;
+++ /dev/null
-/*
- * 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 "ast.h"
-#include "glsl_parser_extras.h"
-#include "glsl_parser.h"
-
-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";
- case ir_shader: break;
- }
-
- assert(!"Should not get here.");
-}
-
-
-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_texture_rectangle") == 0) {
- state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
- state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
- } 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->constant)
- printf("const ");
-
- if (q->invariant)
- printf("invariant ");
-
- if (q->attribute)
- printf("attribute ");
-
- if (q->varying)
- printf("varying ");
-
- if (q->in && q->out)
- printf("inout ");
- else {
- if (q->in)
- printf("in ");
-
- if (q->out)
- printf("out ");
- }
-
- if (q->centroid)
- printf("centroid ");
- if (q->uniform)
- printf("uniform ");
- if (q->smooth)
- printf("smooth ");
- if (q->flat)
- printf("flat ");
- if (q->noperspective)
- printf("noperspective ");
-}
-
-
-void
-ast_node::print(void) const
-{
- printf("unhandled node ");
-}
-
-
-ast_node::ast_node(void)
-{
- /* empty */
-}
-
-
-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;
-}
-
-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)
-{
- name = identifier;
- this->declarations.push_degenerate_list_at_head(&declarator_list->link);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-#ifndef GLSL_PARSER_EXTRAS_H
-#define GLSL_PARSER_EXTRAS_H
-
-#include <cstdlib>
-#include "glsl_symbol_table.h"
-
-enum _mesa_glsl_parser_targets {
- vertex_shader,
- geometry_shader,
- fragment_shader,
- ir_shader
-};
-
-struct _mesa_glsl_parse_state {
- void *scanner;
- exec_list translation_unit;
- glsl_symbol_table *symbols;
-
- unsigned language_version;
- enum _mesa_glsl_parser_targets target;
-
- /**
- * During AST to IR conversion, pointer to current IR function
- *
- * Will be \c NULL whenever the AST to IR conversion is not inside a
- * function definition.
- */
- class ir_function_signature *current_function;
-
- /** Was there an error during compilation? */
- bool error;
-
- /** Index of last generated anonymous temporary. */
- unsigned temp_index;
-
- /** Loop or switch statement containing the current instructions. */
- class ir_instruction *loop_or_switch_nesting;
-
- /** List of structures defined in user code. */
- const glsl_type **user_structures;
- unsigned num_user_structures;
-
- char *info_log;
-
- /**
- * \name Enable bits for GLSL extensions
- */
- /*@{*/
- unsigned ARB_draw_buffers_enable:1;
- unsigned ARB_draw_buffers_warn:1;
- unsigned ARB_texture_rectangle_enable:1;
- unsigned ARB_texture_rectangle_warn:1;
- unsigned EXT_texture_array_enable:1;
- unsigned EXT_texture_array_warn:1;
- /*@}*/
-};
-
-typedef struct YYLTYPE {
- int first_line;
- int first_column;
- int last_line;
- int last_column;
- unsigned source;
-} YYLTYPE;
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-
-extern void _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
- const char *fmt, ...);
-
-/**
- * Emit a warning to the shader log
- *
- * \sa _mesa_glsl_error
- */
-extern void _mesa_glsl_warning(const YYLTYPE *locp,
- _mesa_glsl_parse_state *state,
- const char *fmt, ...);
-
-extern "C" {
-extern int preprocess(void *ctx, const char **shader, char **info_log);
-}
-
-extern void _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state,
- const char *string);
-
-extern void _mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state);
-
-union YYSTYPE;
-extern int _mesa_glsl_lex(union YYSTYPE *yylval, YYLTYPE *yylloc,
- void *scanner);
-
-extern int _mesa_glsl_parse(struct _mesa_glsl_parse_state *);
-
-/**
- * Process elements of the #extension directive
- *
- * \return
- * If \c name and \c behavior are valid, \c true is returned. Otherwise
- * \c false is returned.
- */
-extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
- const char *behavior,
- YYLTYPE *behavior_locp,
- _mesa_glsl_parse_state *state);
-
-/**
- * Get the textual name of the specified shader target
- */
-extern const char *
-_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target);
-
-void do_ir_to_mesa(exec_list *instructions);
-
-#endif /* GLSL_PARSER_EXTRAS_H */
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#pragma once
-#ifndef GLSL_SYMBOL_TABLE
-#define GLSL_SYMBOL_TABLE
-
-#include <new>
-
-#include "symbol_table.h"
-#include "ir.h"
-#include "glsl_types.h"
-
-/**
- * Facade class for _mesa_symbol_table
- *
- * Wraps the existing \c _mesa_symbol_table data structure to enforce some
- * type safe and some symbol table invariants.
- */
-class glsl_symbol_table {
-private:
- enum glsl_symbol_name_space {
- glsl_variable_name_space = 0,
- glsl_type_name_space = 1,
- glsl_function_name_space = 2
- };
-
- static int
- _glsl_symbol_table_destructor (glsl_symbol_table *table)
- {
- table->~glsl_symbol_table();
-
- return 0;
- }
-
-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 *table;
-
- table = talloc_size(ctx, size);
- assert(table != NULL);
-
- talloc_set_destructor(table, (int (*)(void*)) _glsl_symbol_table_destructor);
-
- return table;
- }
-
- /* If the user *does* call delete, that's OK, we will just
- * talloc_free in that case. Here, C++ will have already called the
- * destructor so tell talloc not to do that again. */
- static void operator delete(void *table)
- {
- talloc_set_destructor(table, NULL);
- talloc_free(table);
- }
-
- glsl_symbol_table()
- {
- table = _mesa_symbol_table_ctor();
- }
-
- ~glsl_symbol_table()
- {
- _mesa_symbol_table_dtor(table);
- }
-
- void push_scope()
- {
- _mesa_symbol_table_push_scope(table);
- }
-
- void pop_scope()
- {
- _mesa_symbol_table_pop_scope(table);
- }
-
- /**
- * Determine whether a name was declared at the current scope
- */
- bool name_declared_this_scope(const char *name)
- {
- return _mesa_symbol_table_symbol_scope(table, -1, name) == 0;
- }
-
- /**
- * \name Methods to add symbols to the table
- *
- * There is some temptation to rename all these functions to \c add_symbol
- * or similar. However, this breaks symmetry with the getter functions and
- * reduces the clarity of the intention of code that uses these methods.
- */
- /*@{*/
- bool add_variable(const char *name, ir_variable *v)
- {
- return _mesa_symbol_table_add_symbol(table, glsl_variable_name_space,
- name, v) == 0;
- }
-
- bool add_type(const char *name, const glsl_type *t)
- {
- return _mesa_symbol_table_add_symbol(table, glsl_type_name_space,
- name, (void *) t) == 0;
- }
-
- bool add_function(const char *name, ir_function *f)
- {
- return _mesa_symbol_table_add_symbol(table, glsl_function_name_space,
- name, f) == 0;
- }
- /*@}*/
-
- /**
- * \name Methods to get symbols from the table
- */
- /*@{*/
- ir_variable *get_variable(const char *name)
- {
- return (ir_variable *)
- _mesa_symbol_table_find_symbol(table, glsl_variable_name_space, name);
- }
-
- glsl_type *get_type(const char *name)
- {
- return (glsl_type *)
- _mesa_symbol_table_find_symbol(table, glsl_type_name_space, name);
- }
-
- ir_function *get_function(const char *name)
- {
- return (ir_function *)
- _mesa_symbol_table_find_symbol(table, glsl_function_name_space, name);
- }
- /*@}*/
-
-private:
- struct _mesa_symbol_table *table;
-};
-
-#endif /* GLSL_SYMBOL_TABLE */
+++ /dev/null
-/*
- * 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.
- */
-
-#include <cstdio>
-#include <stdlib.h>
-#include "glsl_symbol_table.h"
-#include "glsl_parser_extras.h"
-#include "glsl_types.h"
-#include "builtin_types.h"
-#include "hash_table.h"
-
-
-hash_table *glsl_type::array_types = NULL;
-
-static void
-add_types_to_symbol_table(glsl_symbol_table *symtab,
- const struct glsl_type *types,
- unsigned num_types, bool warn)
-{
- (void) warn;
-
- for (unsigned i = 0; i < num_types; i++) {
- symtab->add_type(types[i].name, & types[i]);
- }
-}
-
-
-static void
-generate_110_types(glsl_symbol_table *symtab)
-{
- add_types_to_symbol_table(symtab, builtin_core_types,
- Elements(builtin_core_types),
- false);
- add_types_to_symbol_table(symtab, builtin_structure_types,
- Elements(builtin_structure_types),
- false);
- add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
- Elements(builtin_110_deprecated_structure_types),
- false);
- add_types_to_symbol_table(symtab, & void_type, 1, false);
-}
-
-
-static void
-generate_120_types(glsl_symbol_table *symtab)
-{
- generate_110_types(symtab);
-
- add_types_to_symbol_table(symtab, builtin_120_types,
- Elements(builtin_120_types), false);
-}
-
-
-static void
-generate_130_types(glsl_symbol_table *symtab)
-{
- generate_120_types(symtab);
-
- add_types_to_symbol_table(symtab, builtin_130_types,
- Elements(builtin_130_types), false);
-}
-
-
-static void
-generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab, bool warn)
-{
- add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
- Elements(builtin_ARB_texture_rectangle_types),
- warn);
-}
-
-
-static void
-generate_EXT_texture_array_types(glsl_symbol_table *symtab, bool warn)
-{
- add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
- Elements(builtin_EXT_texture_array_types),
- warn);
-}
-
-
-void
-_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
-{
- switch (state->language_version) {
- case 110:
- generate_110_types(state->symbols);
- break;
- case 120:
- generate_120_types(state->symbols);
- break;
- case 130:
- generate_130_types(state->symbols);
- break;
- default:
- /* error */
- break;
- }
-
- if (state->ARB_texture_rectangle_enable) {
- generate_ARB_texture_rectangle_types(state->symbols,
- state->ARB_texture_rectangle_warn);
- }
-
- if (state->EXT_texture_array_enable && state->language_version < 130) {
- // These are already included in 130; don't create twice.
- generate_EXT_texture_array_types(state->symbols,
- state->EXT_texture_array_warn);
- }
-}
-
-
-const glsl_type *glsl_type::get_base_type() const
-{
- switch (base_type) {
- case GLSL_TYPE_UINT:
- return uint_type;
- case GLSL_TYPE_INT:
- return int_type;
- case GLSL_TYPE_FLOAT:
- return float_type;
- case GLSL_TYPE_BOOL:
- return bool_type;
- default:
- return error_type;
- }
-}
-
-
-ir_function *
-glsl_type::generate_constructor(glsl_symbol_table *symtab) const
-{
- void *ctx = symtab;
-
- /* Generate the function name and add it to the symbol table.
- */
- ir_function *const f = new(ctx) ir_function(name);
-
- bool added = symtab->add_function(name, f);
- assert(added);
-
- ir_function_signature *const sig = new(ctx) ir_function_signature(this);
- f->add_signature(sig);
-
- ir_variable **declarations =
- (ir_variable **) malloc(sizeof(ir_variable *) * this->length);
- for (unsigned i = 0; i < length; i++) {
- char *const param_name = (char *) malloc(10);
-
- snprintf(param_name, 10, "p%08X", i);
-
- ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY)
- ? new(ctx) ir_variable(fields.array, param_name)
- : new(ctx) ir_variable(fields.structure[i].type, param_name);
-
- var->mode = ir_var_in;
- declarations[i] = var;
- sig->parameters.push_tail(var);
- }
-
- /* Generate the body of the constructor. The body assigns each of the
- * parameters to a portion of a local variable called __retval that has
- * the same type as the constructor. After initializing __retval,
- * __retval is returned.
- */
- ir_variable *retval = new(ctx) ir_variable(this, "__retval");
- sig->body.push_tail(retval);
-
- for (unsigned i = 0; i < length; i++) {
- ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY)
- ? (ir_dereference *) new(ctx) ir_dereference_array(retval,
- new(ctx) ir_constant(i))
- : (ir_dereference *) new(ctx) ir_dereference_record(retval,
- fields.structure[i].name);
-
- ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
- ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL);
-
- sig->body.push_tail(assign);
- }
-
- free(declarations);
-
- ir_dereference *const retref = new(ctx) ir_dereference_variable(retval);
- ir_instruction *const inst = new(ctx) ir_return(retref);
- sig->body.push_tail(inst);
-
- return f;
-}
-
-
-/**
- * Generate the function intro for a constructor
- *
- * \param type Data type to be constructed
- * \param count Number of parameters to this concrete constructor. Most
- * types have at least two constructors. One will take a
- * single scalar parameter and the other will take "N"
- * scalar parameters.
- * \param parameters Storage for the list of parameters. These are
- * typically stored in an \c ir_function_signature.
- * \param declarations Pointers to the variable declarations for the function
- * parameters. These are used later to avoid having to use
- * the symbol table.
- */
-static ir_function_signature *
-generate_constructor_intro(void *ctx,
- const glsl_type *type, unsigned parameter_count,
- ir_variable **declarations)
-{
- /* Names of parameters used in vector and matrix constructors
- */
- static const char *const names[] = {
- "a", "b", "c", "d", "e", "f", "g", "h",
- "i", "j", "k", "l", "m", "n", "o", "p",
- };
-
- assert(parameter_count <= Elements(names));
-
- const glsl_type *const parameter_type = type->get_base_type();
-
- ir_function_signature *const signature = new(ctx) ir_function_signature(type);
-
- for (unsigned i = 0; i < parameter_count; i++) {
- ir_variable *var = new(ctx) ir_variable(parameter_type, names[i]);
-
- var->mode = ir_var_in;
- signature->parameters.push_tail(var);
-
- declarations[i] = var;
- }
-
- ir_variable *retval = new(ctx) ir_variable(type, "__retval");
- signature->body.push_tail(retval);
-
- declarations[16] = retval;
- return signature;
-}
-
-
-/**
- * Generate the body of a vector constructor that takes a single scalar
- */
-static void
-generate_vec_body_from_scalar(void *ctx,
- exec_list *instructions,
- ir_variable **declarations)
-{
- ir_instruction *inst;
-
- /* Generate a single assignment of the parameter to __retval.x and return
- * __retval.xxxx for however many vector components there are.
- */
- ir_dereference *const lhs_ref =
- new(ctx) ir_dereference_variable(declarations[16]);
- ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
-
- ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
-
- inst = new(ctx) ir_assignment(lhs, rhs, NULL);
- instructions->push_tail(inst);
-
- ir_dereference *const retref = new(ctx) ir_dereference_variable(declarations[16]);
-
- ir_swizzle *retval = new(ctx) ir_swizzle(retref, 0, 0, 0, 0,
- declarations[16]->type->vector_elements);
-
- inst = new(ctx) ir_return(retval);
- instructions->push_tail(inst);
-}
-
-
-/**
- * Generate the body of a vector constructor that takes multiple scalars
- */
-static void
-generate_vec_body_from_N_scalars(void *ctx,
- exec_list *instructions,
- ir_variable **declarations)
-{
- ir_instruction *inst;
- const glsl_type *const vec_type = declarations[16]->type;
-
- /* Generate an assignment of each parameter to a single component of
- * __retval.x and return __retval.
- */
- for (unsigned i = 0; i < vec_type->vector_elements; i++) {
- ir_dereference *const lhs_ref =
- new(ctx) ir_dereference_variable(declarations[16]);
- ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
-
- ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
-
- inst = new(ctx) ir_assignment(lhs, rhs, NULL);
- instructions->push_tail(inst);
- }
-
- ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
-
- inst = new(ctx) ir_return(retval);
- instructions->push_tail(inst);
-}
-
-
-/**
- * Generate the body of a matrix constructor that takes a single scalar
- */
-static void
-generate_mat_body_from_scalar(void *ctx,
- exec_list *instructions,
- ir_variable **declarations)
-{
- ir_instruction *inst;
-
- /* Generate an assignment of the parameter to the X component of a
- * temporary vector. Set the remaining fields of the vector to 0. The
- * size of the vector is equal to the number of rows of the matrix.
- *
- * Set each column of the matrix to a successive "rotation" of the
- * temporary vector. This fills the matrix with 0s, but writes the single
- * scalar along the matrix's diagonal.
- *
- * For a mat4x3, this is equivalent to:
- *
- * vec3 tmp;
- * mat4x3 __retval;
- * tmp.x = a;
- * tmp.y = 0.0;
- * tmp.z = 0.0;
- * __retval[0] = tmp.xyy;
- * __retval[1] = tmp.yxy;
- * __retval[2] = tmp.yyx;
- * __retval[3] = tmp.yyy;
- */
- const glsl_type *const column_type = declarations[16]->type->column_type();
- const glsl_type *const row_type = declarations[16]->type->row_type();
-
- ir_variable *const column = new(ctx) ir_variable(column_type, "v");
-
- instructions->push_tail(column);
-
- ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
- ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
-
- ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
-
- inst = new(ctx) ir_assignment(lhs, rhs, NULL);
- instructions->push_tail(inst);
-
- for (unsigned i = 1; i < column_type->vector_elements; i++) {
- ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
- ir_constant *const zero = new(ctx) ir_constant(0.0f);
-
- ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
-
- inst = new(ctx) ir_assignment(lhs, zero, NULL);
- instructions->push_tail(inst);
- }
-
-
- for (unsigned i = 0; i < row_type->vector_elements; i++) {
- static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 };
- ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(column);
-
- /* This will be .xyyy when i=0, .yxyy when i=1, etc.
- */
- ir_swizzle *rhs = new(ctx) ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i],
- swiz[5 - i], swiz[6 - i],
- column_type->vector_elements);
-
- ir_constant *const idx = new(ctx) ir_constant(int(i));
- ir_dereference *const lhs =
- new(ctx) ir_dereference_array(declarations[16], idx);
-
- inst = new(ctx) ir_assignment(lhs, rhs, NULL);
- instructions->push_tail(inst);
- }
-
- ir_dereference *const retval = new(ctx) ir_dereference_variable(declarations[16]);
- inst = new(ctx) ir_return(retval);
- instructions->push_tail(inst);
-}
-
-
-/**
- * Generate the body of a vector constructor that takes multiple scalars
- */
-static void
-generate_mat_body_from_N_scalars(void *ctx,
- exec_list *instructions,
- ir_variable **declarations)
-{
- ir_instruction *inst;
- const glsl_type *const row_type = declarations[16]->type->row_type();
- const glsl_type *const column_type = declarations[16]->type->column_type();
-
- /* Generate an assignment of each parameter to a single component of
- * of a particular column of __retval and return __retval.
- */
- for (unsigned i = 0; i < column_type->vector_elements; i++) {
- for (unsigned j = 0; j < row_type->vector_elements; j++) {
- ir_constant *row_index = new(ctx) ir_constant(int(i));
- ir_dereference *const row_access =
- new(ctx) ir_dereference_array(declarations[16], row_index);
-
- ir_swizzle *component_access = new(ctx) ir_swizzle(row_access,
- j, 0, 0, 0, 1);
-
- const unsigned param = (i * row_type->vector_elements) + j;
- ir_dereference *const rhs =
- new(ctx) ir_dereference_variable(declarations[param]);
-
- inst = new(ctx) ir_assignment(component_access, rhs, NULL);
- instructions->push_tail(inst);
- }
- }
-
- ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
-
- inst = new(ctx) ir_return(retval);
- instructions->push_tail(inst);
-}
-
-
-/**
- * Generate the constructors for a set of GLSL types
- *
- * Constructor implementations are added to \c instructions, and the symbols
- * are added to \c symtab.
- */
-static void
-generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
- unsigned num_types, exec_list *instructions)
-{
- void *ctx = symtab;
- ir_variable *declarations[17];
-
- for (unsigned i = 0; i < num_types; i++) {
- /* Only numeric and boolean vectors and matrices get constructors here.
- * Structures need to be handled elsewhere. It is expected that scalar
- * constructors are never actually called, so they are not generated.
- */
- if (!types[i].is_numeric() && !types[i].is_boolean())
- continue;
-
- if (types[i].is_scalar())
- continue;
-
- /* Generate the function block, add it to the symbol table, and emit it.
- */
- ir_function *const f = new(ctx) ir_function(types[i].name);
-
- bool added = symtab->add_function(types[i].name, f);
- assert(added);
-
- instructions->push_tail(f);
-
- /* Each type has several basic constructors. The total number of forms
- * depends on the derived type.
- *
- * Vectors: 1 scalar, N scalars
- * Matrices: 1 scalar, NxM scalars
- *
- * Several possible types of constructors are not included in this list.
- *
- * Scalar constructors are not included. The expectation is that the
- * IR generator won't actually generate these as constructor calls. The
- * expectation is that it will just generate the necessary type
- * conversion.
- *
- * Matrix contructors from matrices are also not included. The
- * expectation is that the IR generator will generate a call to the
- * appropriate from-scalars constructor.
- */
- ir_function_signature *const sig =
- generate_constructor_intro(ctx, &types[i], 1, declarations);
- f->add_signature(sig);
-
- if (types[i].is_vector()) {
- generate_vec_body_from_scalar(ctx, &sig->body, declarations);
-
- ir_function_signature *const vec_sig =
- generate_constructor_intro(ctx,
- &types[i], types[i].vector_elements,
- declarations);
- f->add_signature(vec_sig);
-
- generate_vec_body_from_N_scalars(ctx, &vec_sig->body, declarations);
- } else {
- assert(types[i].is_matrix());
-
- generate_mat_body_from_scalar(ctx, &sig->body, declarations);
-
- ir_function_signature *const mat_sig =
- generate_constructor_intro(ctx,
- &types[i],
- (types[i].vector_elements
- * types[i].matrix_columns),
- declarations);
- f->add_signature(mat_sig);
-
- generate_mat_body_from_N_scalars(ctx, &mat_sig->body, declarations);
- }
- }
-}
-
-
-void
-generate_110_constructors(glsl_symbol_table *symtab, exec_list *instructions)
-{
- generate_constructor(symtab, builtin_core_types,
- Elements(builtin_core_types), instructions);
-}
-
-
-void
-generate_120_constructors(glsl_symbol_table *symtab, exec_list *instructions)
-{
- generate_110_constructors(symtab, instructions);
-
- generate_constructor(symtab, builtin_120_types,
- Elements(builtin_120_types), instructions);
-}
-
-
-void
-generate_130_constructors(glsl_symbol_table *symtab, exec_list *instructions)
-{
- generate_120_constructors(symtab, instructions);
-
- generate_constructor(symtab, builtin_130_types,
- Elements(builtin_130_types), instructions);
-}
-
-
-void
-_mesa_glsl_initialize_constructors(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- switch (state->language_version) {
- case 110:
- generate_110_constructors(state->symbols, instructions);
- break;
- case 120:
- generate_120_constructors(state->symbols, instructions);
- break;
- case 130:
- generate_130_constructors(state->symbols, instructions);
- break;
- default:
- /* error */
- break;
- }
-}
-
-
-glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) :
- base_type(GLSL_TYPE_ARRAY),
- sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0),
- vector_elements(0), matrix_columns(0),
- name(NULL), length(length)
-{
- this->fields.array = array;
-
- /* Allow a maximum of 10 characters for the array size. This is enough
- * for 32-bits of ~0. The extra 3 are for the '[', ']', and terminating
- * NUL.
- */
- const unsigned name_length = strlen(array->name) + 10 + 3;
- char *const n = (char *) talloc_size(ctx, name_length);
-
- if (length == 0)
- snprintf(n, name_length, "%s[]", array->name);
- else
- snprintf(n, name_length, "%s[%u]", array->name, length);
-
- this->name = n;
-}
-
-
-const glsl_type *
-glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
-{
- if (base_type == GLSL_TYPE_VOID)
- return &void_type;
-
- if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
- return error_type;
-
- /* Treat GLSL vectors as Nx1 matrices.
- */
- if (columns == 1) {
- switch (base_type) {
- case GLSL_TYPE_UINT:
- return uint_type + (rows - 1);
- case GLSL_TYPE_INT:
- return int_type + (rows - 1);
- case GLSL_TYPE_FLOAT:
- return float_type + (rows - 1);
- case GLSL_TYPE_BOOL:
- return bool_type + (rows - 1);
- default:
- return error_type;
- }
- } else {
- if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
- return error_type;
-
- /* GLSL matrix types are named mat{COLUMNS}x{ROWS}. Only the following
- * combinations are valid:
- *
- * 1 2 3 4
- * 1
- * 2 x x x
- * 3 x x x
- * 4 x x x
- */
-#define IDX(c,r) (((c-1)*3) + (r-1))
-
- switch (IDX(columns, rows)) {
- case IDX(2,2): return mat2_type;
- case IDX(2,3): return mat2x3_type;
- case IDX(2,4): return mat2x4_type;
- case IDX(3,2): return mat3x2_type;
- case IDX(3,3): return mat3_type;
- case IDX(3,4): return mat3x4_type;
- case IDX(4,2): return mat4x2_type;
- case IDX(4,3): return mat4x3_type;
- case IDX(4,4): return mat4_type;
- default: return error_type;
- }
- }
-
- assert(!"Should not get here.");
- return error_type;
-}
-
-
-int
-glsl_type::array_key_compare(const void *a, const void *b)
-{
- const glsl_type *const key1 = (glsl_type *) a;
- const glsl_type *const key2 = (glsl_type *) b;
-
- /* Return zero is the types match (there is zero difference) or non-zero
- * otherwise.
- */
- return ((key1->fields.array == key2->fields.array)
- && (key1->length == key2->length)) ? 0 : 1;
-}
-
-
-unsigned
-glsl_type::array_key_hash(const void *a)
-{
- const glsl_type *const key = (glsl_type *) a;
-
- const struct {
- const glsl_type *t;
- unsigned l;
- char nul;
- } hash_key = {
- key->fields.array,
- key->length,
- '\0'
- };
-
- return hash_table_string_hash(& hash_key);
-}
-
-
-const glsl_type *
-glsl_type::get_array_instance(void *ctx, const glsl_type *base,
- unsigned array_size)
-{
- const glsl_type key(ctx, base, array_size);
-
- if (array_types == NULL) {
- array_types = hash_table_ctor(64, array_key_hash, array_key_compare);
- }
-
- const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key);
- if (t == NULL) {
- t = new(ctx) glsl_type(ctx, base, array_size);
-
- hash_table_insert(array_types, (void *) t, t);
- }
-
- assert(t->base_type == GLSL_TYPE_ARRAY);
- assert(t->length == array_size);
- assert(t->fields.array == base);
-
- return t;
-}
-
-
-const glsl_type *
-glsl_type::field_type(const char *name) const
-{
- if (this->base_type != GLSL_TYPE_STRUCT)
- return error_type;
-
- for (unsigned i = 0; i < this->length; i++) {
- if (strcmp(name, this->fields.structure[i].name) == 0)
- return this->fields.structure[i].type;
- }
-
- return error_type;
-}
-
-
-int
-glsl_type::field_index(const char *name) const
-{
- if (this->base_type != GLSL_TYPE_STRUCT)
- return -1;
-
- for (unsigned i = 0; i < this->length; i++) {
- if (strcmp(name, this->fields.structure[i].name) == 0)
- return i;
- }
-
- return -1;
-}
-
-
-unsigned
-glsl_type::component_slots() const
-{
- switch (this->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_BOOL:
- return this->components();
-
- case GLSL_TYPE_STRUCT: {
- unsigned size = 0;
-
- for (unsigned i = 0; i < this->length; i++)
- size += this->fields.structure[i].type->component_slots();
-
- return size;
- }
-
- case GLSL_TYPE_ARRAY:
- return this->length * this->fields.array->component_slots();
-
- default:
- return 0;
- }
-}
+++ /dev/null
-/* -*- 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 GLSL_TYPES_H
-#define GLSL_TYPES_H
-
-#include <cstring>
-#include <cassert>
-
-extern "C" {
-#include <talloc.h>
-}
-
-#define GLSL_TYPE_UINT 0
-#define GLSL_TYPE_INT 1
-#define GLSL_TYPE_FLOAT 2
-#define GLSL_TYPE_BOOL 3
-#define GLSL_TYPE_SAMPLER 4
-#define GLSL_TYPE_STRUCT 5
-#define GLSL_TYPE_ARRAY 6
-#define GLSL_TYPE_FUNCTION 7
-#define GLSL_TYPE_VOID 8
-#define GLSL_TYPE_ERROR 9
-
-enum glsl_sampler_dim {
- GLSL_SAMPLER_DIM_1D = 0,
- GLSL_SAMPLER_DIM_2D,
- GLSL_SAMPLER_DIM_3D,
- GLSL_SAMPLER_DIM_CUBE,
- GLSL_SAMPLER_DIM_RECT,
- GLSL_SAMPLER_DIM_BUF
-};
-
-
-struct glsl_type {
- unsigned base_type:4;
-
- unsigned sampler_dimensionality:3;
- unsigned sampler_shadow:1;
- unsigned sampler_array:1;
- unsigned sampler_type:2; /**< Type of data returned using this sampler.
- * only \c GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
- * and \c GLSL_TYPE_UINT are valid.
- */
-
- /* 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 *type;
-
- type = talloc_size(ctx, size);
- assert(type != NULL);
-
- return type;
- }
-
- /* If the user *does* call delete, that's OK, we will just
- * talloc_free in that case. */
- static void operator delete(void *type)
- {
- talloc_free(type);
- }
-
- /**
- * \name Vector and matrix element counts
- *
- * For scalars, each of these values will be 1. For non-numeric types
- * these will be 0.
- */
- /*@{*/
- unsigned vector_elements:3; /**< 1, 2, 3, or 4 vector elements. */
- unsigned matrix_columns:3; /**< 1, 2, 3, or 4 matrix columns. */
- /*@}*/
-
- /**
- * Name of the data type
- *
- * This may be \c NULL for anonymous structures, for arrays, or for
- * function types.
- */
- const char *name;
-
- /**
- * For \c GLSL_TYPE_ARRAY, this is the length of the array. For
- * \c GLSL_TYPE_STRUCT, it is the number of elements in the structure and
- * the number of values pointed to by \c fields.structure (below).
- *
- * For \c GLSL_TYPE_FUNCTION, it is the number of parameters to the
- * function. The return value from a function is implicitly the first
- * parameter. The types of the parameters are stored in
- * \c fields.parameters (below).
- */
- unsigned length;
-
- /**
- * Subtype of composite data types.
- */
- union {
- const struct glsl_type *array; /**< Type of array elements. */
- const struct glsl_type *parameters; /**< Parameters to function. */
- const struct glsl_struct_field *structure;/**< List of struct fields. */
- } fields;
-
-
- /**
- * \name Pointers to various public type singletons
- */
- /*@{*/
- static const glsl_type *const error_type;
- static const glsl_type *const int_type;
- static const glsl_type *const ivec4_type;
- static const glsl_type *const uint_type;
- static const glsl_type *const uvec4_type;
- static const glsl_type *const float_type;
- static const glsl_type *const vec2_type;
- static const glsl_type *const vec3_type;
- static const glsl_type *const vec4_type;
- static const glsl_type *const bool_type;
- static const glsl_type *const mat2_type;
- static const glsl_type *const mat2x3_type;
- static const glsl_type *const mat2x4_type;
- static const glsl_type *const mat3x2_type;
- static const glsl_type *const mat3_type;
- static const glsl_type *const mat3x4_type;
- static const glsl_type *const mat4x2_type;
- static const glsl_type *const mat4x3_type;
- static const glsl_type *const mat4_type;
- /*@}*/
-
-
- glsl_type(unsigned base_type, unsigned vector_elements,
- unsigned matrix_columns, const char *name) :
- base_type(base_type),
- sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0),
- vector_elements(vector_elements), matrix_columns(matrix_columns),
- name(name),
- length(0)
- {
- /* Neither dimension is zero or both dimensions are zero.
- */
- assert((vector_elements == 0) == (matrix_columns == 0));
- memset(& fields, 0, sizeof(fields));
- }
-
- glsl_type(enum glsl_sampler_dim dim, bool shadow, bool array,
- unsigned type, const char *name) :
- base_type(GLSL_TYPE_SAMPLER),
- sampler_dimensionality(dim), sampler_shadow(shadow),
- sampler_array(array), sampler_type(type),
- vector_elements(0), matrix_columns(0),
- name(name),
- length(0)
- {
- memset(& fields, 0, sizeof(fields));
- }
-
- glsl_type(const glsl_struct_field *fields, unsigned num_fields,
- const char *name) :
- base_type(GLSL_TYPE_STRUCT),
- sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0),
- vector_elements(0), matrix_columns(0),
- name(name),
- length(num_fields)
- {
- this->fields.structure = fields;
- }
-
- /**
- * For numeric and boolean derrived types returns the basic scalar type
- *
- * If the type is a numeric or boolean scalar, vector, or matrix type,
- * this function gets the scalar type of the individual components. For
- * all other types, including arrays of numeric or boolean types, the
- * error type is returned.
- */
- const glsl_type *get_base_type() const;
-
- /**
- * Query the type of elements in an array
- *
- * \return
- * Pointer to the type of elements in the array for array types, or \c NULL
- * for non-array types.
- */
- const glsl_type *element_type() const
- {
- return is_array() ? fields.array : NULL;
- }
-
- /**
- * Get the instance of a built-in scalar, vector, or matrix type
- */
- static const glsl_type *get_instance(unsigned base_type, unsigned rows,
- unsigned columns);
-
- /**
- * Get the instance of an array type
- */
- static const glsl_type *get_array_instance(void *ctx,
- const glsl_type *base,
- unsigned elements);
-
- /**
- * Generate the constructor for this type and add it to the symbol table
- */
- class ir_function *generate_constructor(class glsl_symbol_table *) const;
-
- /**
- * Query the total number of scalars that make up a scalar, vector or matrix
- */
- unsigned components() const
- {
- return vector_elements * matrix_columns;
- }
-
- /**
- * Calculate the number of components slots required to hold this type
- *
- * This is used to determine how many uniform or varying locations a type
- * might occupy.
- */
- unsigned component_slots() const;
-
-
- /**
- * Query whether or not a type is a scalar (non-vector and non-matrix).
- */
- bool is_scalar() const
- {
- return (vector_elements == 1)
- && (base_type >= GLSL_TYPE_UINT)
- && (base_type <= GLSL_TYPE_BOOL);
- }
-
- /**
- * Query whether or not a type is a vector
- */
- bool is_vector() const
- {
- return (vector_elements > 1)
- && (matrix_columns == 1)
- && (base_type >= GLSL_TYPE_UINT)
- && (base_type <= GLSL_TYPE_BOOL);
- }
-
- /**
- * Query whether or not a type is a matrix
- */
- bool is_matrix() const
- {
- /* GLSL only has float matrices. */
- return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT);
- }
-
- /**
- * Query whether or not a type is a non-array numeric type
- */
- bool is_numeric() const
- {
- return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_FLOAT);
- }
-
- /**
- * Query whether or not a type is an integral type
- */
- bool is_integer() const
- {
- return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT);
- }
-
- /**
- * Query whether or not a type is a float type
- */
- bool is_float() const
- {
- return base_type == GLSL_TYPE_FLOAT;
- }
-
- /**
- * Query whether or not a type is a non-array boolean type
- */
- bool is_boolean() const
- {
- return base_type == GLSL_TYPE_BOOL;
- }
-
- /**
- * Query whether or not a type is a sampler
- */
- bool is_sampler() const
- {
- return base_type == GLSL_TYPE_SAMPLER;
- }
-
- /**
- * Query whether or not a type is an array
- */
- bool is_array() const
- {
- return base_type == GLSL_TYPE_ARRAY;
- }
-
- /**
- * Query whether or not a type is a record
- */
- bool is_record() const
- {
- return base_type == GLSL_TYPE_STRUCT;
- }
-
- /**
- * Query whether or not a type is the void type singleton.
- */
- bool is_void() const
- {
- return base_type == GLSL_TYPE_VOID;
- }
-
- /**
- * Query whether or not a type is the error type singleton.
- */
- bool is_error() const
- {
- return base_type == GLSL_TYPE_ERROR;
- }
-
- /**
- * Query the full type of a matrix row
- *
- * \return
- * If the type is not a matrix, \c glsl_type::error_type is returned.
- * Otherwise a type matching the rows of the matrix is returned.
- */
- const glsl_type *row_type() const
- {
- return is_matrix()
- ? get_instance(base_type, matrix_columns, 1)
- : error_type;
- }
-
- /**
- * Query the full type of a matrix column
- *
- * \return
- * If the type is not a matrix, \c glsl_type::error_type is returned.
- * Otherwise a type matching the columns of the matrix is returned.
- */
- const glsl_type *column_type() const
- {
- return is_matrix()
- ? get_instance(base_type, vector_elements, 1)
- : error_type;
- }
-
-
- /**
- * Get the type of a structure field
- *
- * \return
- * Pointer to the type of the named field. If the type is not a structure
- * or the named field does not exist, \c glsl_type::error_type is returned.
- */
- const glsl_type *field_type(const char *name) const;
-
-
- /**
- * Get the location of a filed within a record type
- */
- int field_index(const char *name) const;
-
-
- /**
- * Query the number of elements in an array type
- *
- * \return
- * The number of elements in the array for array types or -1 for non-array
- * types. If the number of elements in the array has not yet been declared,
- * zero is returned.
- */
- int array_size() const
- {
- return is_array() ? length : -1;
- }
-
-private:
- /**
- * Constructor for array types
- */
- glsl_type(void *ctx, const glsl_type *array, unsigned length);
-
- /** Hash table containing the known array types. */
- static struct hash_table *array_types;
-
- static int array_key_compare(const void *a, const void *b);
- static unsigned array_key_hash(const void *key);
-};
-
-struct glsl_struct_field {
- const struct glsl_type *type;
- const char *name;
-};
-
-struct _mesa_glsl_parse_state;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void
-_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
-
-extern void
-_mesa_glsl_initialize_constructors(struct exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GLSL_TYPES_H */
+++ /dev/null
-/*
- * Copyright © 2008 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.
- */
-
-/**
- * \file hash_table.c
- * \brief Implementation of a generic, opaque hash table data type.
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#include "main/imports.h"
-#include "main/simple_list.h"
-#include "hash_table.h"
-
-struct node {
- struct node *next;
- struct node *prev;
-};
-
-struct hash_table {
- hash_func_t hash;
- hash_compare_func_t compare;
-
- unsigned num_buckets;
- struct node buckets[1];
-};
-
-
-struct hash_node {
- struct node link;
- const void *key;
- void *data;
-};
-
-
-struct hash_table *
-hash_table_ctor(unsigned num_buckets, hash_func_t hash,
- hash_compare_func_t compare)
-{
- struct hash_table *ht;
- unsigned i;
-
-
- if (num_buckets < 16) {
- num_buckets = 16;
- }
-
- ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1)
- * sizeof(ht->buckets[0])));
- if (ht != NULL) {
- ht->hash = hash;
- ht->compare = compare;
- ht->num_buckets = num_buckets;
-
- for (i = 0; i < num_buckets; i++) {
- make_empty_list(& ht->buckets[i]);
- }
- }
-
- return ht;
-}
-
-
-void
-hash_table_dtor(struct hash_table *ht)
-{
- hash_table_clear(ht);
- _mesa_free(ht);
-}
-
-
-void
-hash_table_clear(struct hash_table *ht)
-{
- struct node *node;
- struct node *temp;
- unsigned i;
-
-
- for (i = 0; i < ht->num_buckets; i++) {
- foreach_s(node, temp, & ht->buckets[i]) {
- remove_from_list(node);
- _mesa_free(node);
- }
-
- assert(is_empty_list(& ht->buckets[i]));
- }
-}
-
-
-void *
-hash_table_find(struct hash_table *ht, const void *key)
-{
- const unsigned hash_value = (*ht->hash)(key);
- const unsigned bucket = hash_value % ht->num_buckets;
- struct node *node;
-
- foreach(node, & ht->buckets[bucket]) {
- struct hash_node *hn = (struct hash_node *) node;
-
- if ((*ht->compare)(hn->key, key) == 0) {
- return hn->data;
- }
- }
-
- return NULL;
-}
-
-
-void
-hash_table_insert(struct hash_table *ht, void *data, const void *key)
-{
- const unsigned hash_value = (*ht->hash)(key);
- const unsigned bucket = hash_value % ht->num_buckets;
- struct hash_node *node;
-
- node = _mesa_calloc(sizeof(*node));
-
- node->data = data;
- node->key = key;
-
- insert_at_head(& ht->buckets[bucket], & node->link);
-}
-
-
-unsigned
-hash_table_string_hash(const void *key)
-{
- const char *str = (const char *) key;
- unsigned hash = 5381;
-
-
- while (*str != '\0') {
- hash = (hash * 33) + *str;
- str++;
- }
-
- return hash;
-}
+++ /dev/null
-/*
- * Copyright © 2008 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.
- */
-
-/**
- * \file hash_table.h
- * \brief Implementation of a generic, opaque hash table data type.
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#ifndef HASH_TABLE_H
-#define HASH_TABLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <string.h>
-
-struct hash_table;
-
-typedef unsigned (*hash_func_t)(const void *key);
-typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
-
-/**
- * Hash table constructor
- *
- * Creates a hash table with the specified number of buckets. The supplied
- * \c hash and \c compare routines are used when adding elements to the table
- * and when searching for elements in the table.
- *
- * \param num_buckets Number of buckets (bins) in the hash table.
- * \param hash Function used to compute hash value of input keys.
- * \param compare Function used to compare keys.
- */
-extern struct hash_table *hash_table_ctor(unsigned num_buckets,
- hash_func_t hash, hash_compare_func_t compare);
-
-
-/**
- * Release all memory associated with a hash table
- *
- * \warning
- * This function cannot release memory occupied either by keys or data.
- */
-extern void hash_table_dtor(struct hash_table *ht);
-
-
-/**
- * Flush all entries from a hash table
- *
- * \param ht Table to be cleared of its entries.
- */
-extern void hash_table_clear(struct hash_table *ht);
-
-
-/**
- * Search a hash table for a specific element
- *
- * \param ht Table to be searched
- * \param key Key of the desired element
- *
- * \return
- * The \c data value supplied to \c hash_table_insert when the element with
- * the matching key was added. If no matching key exists in the table,
- * \c NULL is returned.
- */
-extern void *hash_table_find(struct hash_table *ht, const void *key);
-
-
-/**
- * Add an element to a hash table
- */
-extern void hash_table_insert(struct hash_table *ht, void *data,
- const void *key);
-
-
-/**
- * Compute hash value of a string
- *
- * Computes the hash value of a string using the DJB2 algorithm developed by
- * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
- * a time. I was unable to find the original posting in the archives.
- *
- * \param key Pointer to a NUL terminated string to be hashed.
- *
- * \sa hash_table_string_compare
- */
-extern unsigned hash_table_string_hash(const void *key);
-
-
-/**
- * Compare two strings used as keys
- *
- * This is just a macro wrapper around \c strcmp.
- *
- * \sa hash_table_string_hash
- */
-#define hash_table_string_compare ((hash_compare_func_t) strcmp)
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* HASH_TABLE_H */
+++ /dev/null
-/*
- * 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 "ir.h"
-#include "main/imports.h"
-#include "symbol_table.h"
-#include "glsl_parser_extras.h"
-#include "ast.h"
-#include "glsl_types.h"
-
-struct ir_rvalue *
-_mesa_ast_field_selection_to_hir(const ast_expression *expr,
- exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = talloc_parent(state);
- ir_rvalue *result = NULL;
- ir_rvalue *op;
-
- op = expr->subexpressions[0]->hir(instructions, state);
-
- /* There are two kinds of field selection. There is the selection of a
- * specific field from a structure, and there is the selection of a
- * swizzle / mask from a vector. Which is which is determined entirely
- * by the base type of the thing to which the field selection operator is
- * being applied.
- */
- YYLTYPE loc = expr->get_location();
- if (op->type->is_error()) {
- /* silently propagate the error */
- } else if (op->type->is_vector()) {
- ir_swizzle *swiz = ir_swizzle::create(op,
- expr->primary_expression.identifier,
- op->type->vector_elements);
- if (swiz != NULL) {
- result = swiz;
- } else {
- /* FINISHME: Logging of error messages should be moved into
- * FINISHME: ir_swizzle::create. This allows the generation of more
- * FINISHME: specific error messages.
- */
- _mesa_glsl_error(& loc, state, "Invalid swizzle / mask `%s'",
- expr->primary_expression.identifier);
- }
- } else if (op->type->base_type == GLSL_TYPE_STRUCT) {
- result = new(ctx) ir_dereference_record(op,
- expr->primary_expression.identifier);
-
- if (result->type->is_error()) {
- _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
- "structure",
- expr->primary_expression.identifier);
- }
- } else {
- _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
- "non-structure / non-vector.",
- expr->primary_expression.identifier);
- }
-
- return result ? result : ir_call::get_error_instruction(ctx);
-}
+++ /dev/null
-/*
- * 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 <string.h>
-#include "main/imports.h"
-#include "ir.h"
-#include "ir_visitor.h"
-#include "glsl_types.h"
-
-ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
- ir_rvalue *condition)
-{
- this->lhs = lhs;
- this->rhs = rhs;
- this->condition = condition;
-}
-
-
-ir_expression::ir_expression(int op, const struct glsl_type *type,
- ir_rvalue *op0, ir_rvalue *op1)
-{
- this->type = type;
- this->operation = ir_expression_operation(op);
- this->operands[0] = op0;
- this->operands[1] = op1;
-}
-
-unsigned int
-ir_expression::get_num_operands(ir_expression_operation op)
-{
-/* Update ir_print_visitor.cpp when updating this list. */
- const int num_operands[] = {
- 1, /* ir_unop_bit_not */
- 1, /* ir_unop_logic_not */
- 1, /* ir_unop_neg */
- 1, /* ir_unop_abs */
- 1, /* ir_unop_sign */
- 1, /* ir_unop_rcp */
- 1, /* ir_unop_rsq */
- 1, /* ir_unop_sqrt */
- 1, /* ir_unop_exp */
- 1, /* ir_unop_log */
- 1, /* ir_unop_exp2 */
- 1, /* ir_unop_log2 */
- 1, /* ir_unop_f2i */
- 1, /* ir_unop_i2f */
- 1, /* ir_unop_f2b */
- 1, /* ir_unop_b2f */
- 1, /* ir_unop_i2b */
- 1, /* ir_unop_b2i */
- 1, /* ir_unop_u2f */
-
- 1, /* ir_unop_trunc */
- 1, /* ir_unop_ceil */
- 1, /* ir_unop_floor */
-
- 1, /* ir_unop_sin */
- 1, /* ir_unop_cos */
-
- 1, /* ir_unop_dFdx */
- 1, /* ir_unop_dFdy */
-
- 2, /* ir_binop_add */
- 2, /* ir_binop_sub */
- 2, /* ir_binop_mul */
- 2, /* ir_binop_div */
- 2, /* ir_binop_mod */
-
- 2, /* ir_binop_less */
- 2, /* ir_binop_greater */
- 2, /* ir_binop_lequal */
- 2, /* ir_binop_gequal */
- 2, /* ir_binop_equal */
- 2, /* ir_binop_nequal */
-
- 2, /* ir_binop_lshift */
- 2, /* ir_binop_rshift */
- 2, /* ir_binop_bit_and */
- 2, /* ir_binop_bit_xor */
- 2, /* ir_binop_bit_or */
-
- 2, /* ir_binop_logic_and */
- 2, /* ir_binop_logic_xor */
- 2, /* ir_binop_logic_or */
-
- 2, /* ir_binop_dot */
- 2, /* ir_binop_min */
- 2, /* ir_binop_max */
-
- 2, /* ir_binop_pow */
- };
-
- assert(sizeof(num_operands) / sizeof(num_operands[0]) == ir_binop_pow + 1);
-
- return num_operands[op];
-}
-
-static const char *const operator_strs[] = {
- "~",
- "!",
- "neg",
- "abs",
- "sign",
- "rcp",
- "rsq",
- "sqrt",
- "exp",
- "log",
- "exp2",
- "log2",
- "f2i",
- "i2f",
- "f2b",
- "b2f",
- "i2b",
- "b2i",
- "u2f",
- "trunc",
- "ceil",
- "floor",
- "sin",
- "cos",
- "dFdx",
- "dFdy",
- "+",
- "-",
- "*",
- "/",
- "%",
- "<",
- ">",
- "<=",
- ">=",
- "==",
- "!=",
- "<<",
- ">>",
- "&",
- "^",
- "|",
- "&&",
- "^^",
- "||",
- "dot",
- "min",
- "max",
- "pow",
-};
-
-const char *ir_expression::operator_string()
-{
- assert((unsigned int) operation <=
- sizeof(operator_strs) / sizeof(operator_strs[0]));
- return operator_strs[operation];
-}
-
-ir_expression_operation
-ir_expression::get_operator(const char *str)
-{
- const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]);
- for (int op = 0; op < operator_count; op++) {
- if (strcmp(str, operator_strs[op]) == 0)
- return (ir_expression_operation) op;
- }
- return (ir_expression_operation) -1;
-}
-
-ir_constant::ir_constant()
-{
- /* empty */
-}
-
-ir_constant::ir_constant(const struct glsl_type *type,
- const ir_constant_data *data)
-{
- assert((type->base_type >= GLSL_TYPE_UINT)
- && (type->base_type <= GLSL_TYPE_BOOL));
-
- this->type = type;
- memcpy(& this->value, data, sizeof(this->value));
-}
-
-ir_constant::ir_constant(float f)
-{
- this->type = glsl_type::float_type;
- this->value.f[0] = f;
-}
-
-ir_constant::ir_constant(unsigned int u)
-{
- this->type = glsl_type::uint_type;
- this->value.u[0] = u;
-}
-
-ir_constant::ir_constant(int i)
-{
- this->type = glsl_type::int_type;
- this->value.i[0] = i;
-}
-
-ir_constant::ir_constant(bool b)
-{
- this->type = glsl_type::bool_type;
- this->value.b[0] = b;
-}
-
-ir_constant::ir_constant(const ir_constant *c, unsigned i)
-{
- this->type = c->type->get_base_type();
-
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT: this->value.u[0] = c->value.u[i]; break;
- case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break;
- case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
- case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break;
- default: assert(!"Should not get here."); break;
- }
-}
-
-ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
-{
- this->type = type;
-
- /* FINISHME: Support array types. */
- assert(type->is_scalar() || type->is_vector() || type->is_matrix()
- || type->is_record());
-
- /* If the constant is a record, the types of each of the entries in
- * value_list must be a 1-for-1 match with the structure components. Each
- * entry must also be a constant. Just move the nodes from the value_list
- * to the list in the ir_constant.
- */
- /* FINISHME: Should there be some type checking and / or assertions here? */
- /* FINISHME: Should the new constant take ownership of the nodes from
- * FINISHME: value_list, or should it make copies?
- */
- if (type->is_record()) {
- value_list->move_nodes_to(& this->components);
- return;
- }
-
-
- ir_constant *value = (ir_constant *) (value_list->head);
-
- /* Use each component from each entry in the value_list to initialize one
- * component of the constant being constructed.
- */
- for (unsigned i = 0; i < type->components(); /* empty */) {
- assert(value->as_constant() != NULL);
- assert(!value->is_tail_sentinal());
-
- for (unsigned j = 0; j < value->type->components(); j++) {
- switch (type->base_type) {
- case GLSL_TYPE_UINT:
- this->value.u[i] = value->get_uint_component(j);
- break;
- case GLSL_TYPE_INT:
- this->value.i[i] = value->get_int_component(j);
- break;
- case GLSL_TYPE_FLOAT:
- this->value.f[i] = value->get_float_component(j);
- break;
- case GLSL_TYPE_BOOL:
- this->value.b[i] = value->get_bool_component(j);
- break;
- default:
- /* FINISHME: What to do? Exceptions are not the answer.
- */
- break;
- }
-
- i++;
- if (i >= type->components())
- break;
- }
-
- value = (ir_constant *) value->next;
- }
-}
-
-bool
-ir_constant::get_bool_component(unsigned i) const
-{
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT: return this->value.u[i] != 0;
- case GLSL_TYPE_INT: return this->value.i[i] != 0;
- case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
- case GLSL_TYPE_BOOL: return this->value.b[i];
- default: assert(!"Should not get here."); break;
- }
-
- /* Must return something to make the compiler happy. This is clearly an
- * error case.
- */
- return false;
-}
-
-float
-ir_constant::get_float_component(unsigned i) const
-{
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT: return (float) this->value.u[i];
- case GLSL_TYPE_INT: return (float) this->value.i[i];
- case GLSL_TYPE_FLOAT: return this->value.f[i];
- case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0;
- default: assert(!"Should not get here."); break;
- }
-
- /* Must return something to make the compiler happy. This is clearly an
- * error case.
- */
- return 0.0;
-}
-
-int
-ir_constant::get_int_component(unsigned i) const
-{
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT: return this->value.u[i];
- case GLSL_TYPE_INT: return this->value.i[i];
- case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
- case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
- default: assert(!"Should not get here."); break;
- }
-
- /* Must return something to make the compiler happy. This is clearly an
- * error case.
- */
- return 0;
-}
-
-unsigned
-ir_constant::get_uint_component(unsigned i) const
-{
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT: return this->value.u[i];
- case GLSL_TYPE_INT: return this->value.i[i];
- case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
- case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
- default: assert(!"Should not get here."); break;
- }
-
- /* Must return something to make the compiler happy. This is clearly an
- * error case.
- */
- return 0;
-}
-
-
-ir_constant *
-ir_constant::get_record_field(const char *name)
-{
- int idx = this->type->field_index(name);
-
- if (idx < 0)
- return NULL;
-
- if (this->components.is_empty())
- return NULL;
-
- exec_node *node = this->components.head;
- for (int i = 0; i < idx; i++) {
- node = node->next;
-
- /* If the end of the list is encountered before the element matching the
- * requested field is found, return NULL.
- */
- if (node->is_tail_sentinal())
- return NULL;
- }
-
- return (ir_constant *) node;
-}
-
-
-bool
-ir_constant::has_value(const ir_constant *c) const
-{
- if (this->type != c->type)
- return false;
-
- /* FINISHME: This will probably also handle constant arrays as soon as those
- * FINISHME: are supported.
- */
- if (this->type->base_type == GLSL_TYPE_STRUCT) {
- const exec_node *a_node = this->components.head;
- const exec_node *b_node = c->components.head;
-
- while (!a_node->is_tail_sentinal()) {
- assert(!b_node->is_tail_sentinal());
-
- const ir_constant *const a_field = (ir_constant *) a_node;
- const ir_constant *const b_field = (ir_constant *) b_node;
-
- if (!a_field->has_value(b_field))
- return false;
-
- a_node = a_node->next;
- b_node = b_node->next;
- }
-
- return true;
- }
-
- for (unsigned i = 0; i < this->type->components(); i++) {
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT:
- if (this->value.u[i] != c->value.u[i])
- return false;
- break;
- case GLSL_TYPE_INT:
- if (this->value.i[i] != c->value.i[i])
- return false;
- break;
- case GLSL_TYPE_FLOAT:
- if (this->value.f[i] != c->value.f[i])
- return false;
- break;
- case GLSL_TYPE_BOOL:
- if (this->value.b[i] != c->value.b[i])
- return false;
- break;
- default:
- assert(!"Should not get here.");
- return false;
- }
- }
-
- return true;
-}
-
-ir_dereference_variable::ir_dereference_variable(ir_variable *var)
-{
- this->var = var;
- this->type = (var != NULL) ? var->type : glsl_type::error_type;
-}
-
-
-ir_dereference_array::ir_dereference_array(ir_rvalue *value,
- ir_rvalue *array_index)
-{
- this->array_index = array_index;
- this->set_array(value);
-}
-
-
-ir_dereference_array::ir_dereference_array(ir_variable *var,
- ir_rvalue *array_index)
-{
- void *ctx = talloc_parent(var);
-
- this->array_index = array_index;
- this->set_array(new(ctx) ir_dereference_variable(var));
-}
-
-
-void
-ir_dereference_array::set_array(ir_rvalue *value)
-{
- this->array = value;
- this->type = glsl_type::error_type;
-
- if (this->array != NULL) {
- const glsl_type *const vt = this->array->type;
-
- if (vt->is_array()) {
- type = vt->element_type();
- } else if (vt->is_matrix()) {
- type = vt->column_type();
- } else if (vt->is_vector()) {
- type = vt->get_base_type();
- }
- }
-}
-
-
-ir_dereference_record::ir_dereference_record(ir_rvalue *value,
- const char *field)
-{
- this->record = value;
- this->field = field;
- this->type = (this->record != NULL)
- ? this->record->type->field_type(field) : glsl_type::error_type;
-}
-
-
-ir_dereference_record::ir_dereference_record(ir_variable *var,
- const char *field)
-{
- void *ctx = talloc_parent(var);
-
- this->record = new(ctx) ir_dereference_variable(var);
- this->field = field;
- this->type = (this->record != NULL)
- ? this->record->type->field_type(field) : glsl_type::error_type;
-}
-
-
-bool
-ir_dereference::is_lvalue()
-{
- ir_variable *var = this->variable_referenced();
-
- /* Every l-value derference chain eventually ends in a variable.
- */
- if ((var == NULL) || var->read_only)
- return false;
-
- if (this->type->is_array() && !var->array_lvalue)
- return false;
-
- return true;
-}
-
-
-const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
-
-const char *ir_texture::opcode_string()
-{
- assert((unsigned int) op <=
- sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]));
- return tex_opcode_strs[op];
-}
-
-ir_texture_opcode
-ir_texture::get_opcode(const char *str)
-{
- const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
- for (int op = 0; op < count; op++) {
- if (strcmp(str, tex_opcode_strs[op]) == 0)
- return (ir_texture_opcode) op;
- }
- return (ir_texture_opcode) -1;
-}
-
-
-void
-ir_texture::set_sampler(ir_dereference *sampler)
-{
- assert(sampler != NULL);
- this->sampler = sampler;
-
- switch (sampler->type->sampler_type) {
- case GLSL_TYPE_FLOAT:
- this->type = glsl_type::vec4_type;
- break;
- case GLSL_TYPE_INT:
- this->type = glsl_type::ivec4_type;
- break;
- case GLSL_TYPE_UINT:
- this->type = glsl_type::uvec4_type;
- break;
- }
-}
-
-
-ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
- unsigned w, unsigned count)
- : val(val)
-{
- assert((count >= 1) && (count <= 4));
-
- const unsigned dup_mask = 0
- | ((count > 1) ? ((1U << y) & ((1U << x) )) : 0)
- | ((count > 2) ? ((1U << z) & ((1U << x) | (1U << y) )) : 0)
- | ((count > 3) ? ((1U << w) & ((1U << x) | (1U << y) | (1U << z))) : 0);
-
- assert(x <= 3);
- assert(y <= 3);
- assert(z <= 3);
- assert(w <= 3);
-
- mask.x = x;
- mask.y = y;
- mask.z = z;
- mask.w = w;
- mask.num_components = count;
- mask.has_duplicates = dup_mask != 0;
-
- /* Based on the number of elements in the swizzle and the base type
- * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
- * generate the type of the resulting value.
- */
- type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
-}
-
-ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
-{
- this->val = val;
- this->mask = mask;
- this->type = glsl_type::get_instance(val->type->base_type,
- mask.num_components, 1);
-}
-
-#define X 1
-#define R 5
-#define S 9
-#define I 13
-
-ir_swizzle *
-ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
-{
- void *ctx = talloc_parent(val);
-
- /* For each possible swizzle character, this table encodes the value in
- * \c idx_map that represents the 0th element of the vector. For invalid
- * swizzle characters (e.g., 'k'), a special value is used that will allow
- * detection of errors.
- */
- static const unsigned char base_idx[26] = {
- /* a b c d e f g h i j k l m */
- R, R, I, I, I, I, R, I, I, I, I, I, I,
- /* n o p q r s t u v w x y z */
- I, I, S, S, R, S, S, I, I, X, X, X, X
- };
-
- /* Each valid swizzle character has an entry in the previous table. This
- * table encodes the base index encoded in the previous table plus the actual
- * index of the swizzle character. When processing swizzles, the first
- * character in the string is indexed in the previous table. Each character
- * in the string is indexed in this table, and the value found there has the
- * value form the first table subtracted. The result must be on the range
- * [0,3].
- *
- * For example, the string "wzyx" will get X from the first table. Each of
- * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After
- * subtraction, the swizzle values are { 3, 2, 1, 0 }.
- *
- * The string "wzrg" will get X from the first table. Each of the characters
- * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the
- * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range
- * [0,3], the error is detected.
- */
- static const unsigned char idx_map[26] = {
- /* a b c d e f g h i j k l m */
- R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0,
- /* n o p q r s t u v w x y z */
- 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2
- };
-
- int swiz_idx[4] = { 0, 0, 0, 0 };
- unsigned i;
-
-
- /* Validate the first character in the swizzle string and look up the base
- * index value as described above.
- */
- if ((str[0] < 'a') || (str[0] > 'z'))
- return NULL;
-
- const unsigned base = base_idx[str[0] - 'a'];
-
-
- for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
- /* Validate the next character, and, as described above, convert it to a
- * swizzle index.
- */
- if ((str[i] < 'a') || (str[i] > 'z'))
- return NULL;
-
- swiz_idx[i] = idx_map[str[i] - 'a'] - base;
- if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
- return NULL;
- }
-
- if (str[i] != '\0')
- return NULL;
-
- return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
- swiz_idx[3], i);
-}
-
-#undef X
-#undef R
-#undef S
-#undef I
-
-ir_variable *
-ir_swizzle::variable_referenced()
-{
- return this->val->variable_referenced();
-}
-
-ir_variable::ir_variable(const struct glsl_type *type, const char *name)
- : max_array_access(0), read_only(false), centroid(false), invariant(false),
- shader_in(false), shader_out(false),
- mode(ir_var_auto), interpolation(ir_var_smooth), array_lvalue(false)
-{
- this->type = type;
- this->name = name;
- this->location = -1;
- this->warn_extension = NULL;
- this->constant_value = NULL;
-
- if (type && type->base_type == GLSL_TYPE_SAMPLER)
- this->read_only = true;
-}
-
-
-const char *
-ir_variable::interpolation_string() const
-{
- if (!this->shader_in && !this->shader_out)
- return "";
-
- switch (this->interpolation) {
- case ir_var_smooth: return "smooth";
- case ir_var_flat: return "flat";
- case ir_var_noperspective: return "noperspective";
- }
-
- assert(!"Should not get here.");
- return "";
-}
-
-
-unsigned
-ir_variable::component_slots() const
-{
- /* FINISHME: Sparsely accessed arrays require fewer slots. */
- return this->type->component_slots();
-}
-
-
-ir_function_signature::ir_function_signature(const glsl_type *return_type)
- : return_type(return_type), is_defined(false)
-{
- /* empty */
-}
-
-
-const char *
-ir_function_signature::qualifiers_match(exec_list *params)
-{
- exec_list_iterator iter_a = parameters.iterator();
- exec_list_iterator iter_b = params->iterator();
-
- /* check that the qualifiers match. */
- while (iter_a.has_next()) {
- ir_variable *a = (ir_variable *)iter_a.get();
- ir_variable *b = (ir_variable *)iter_b.get();
-
- if (a->read_only != b->read_only ||
- a->mode != b->mode ||
- a->interpolation != b->interpolation ||
- a->centroid != b->centroid) {
-
- /* parameter a's qualifiers don't match */
- return a->name;
- }
-
- iter_a.next();
- iter_b.next();
- }
- return NULL;
-}
-
-
-void
-ir_function_signature::replace_parameters(exec_list *new_params)
-{
- /* Destroy all of the previous parameter information. If the previous
- * parameter information comes from the function prototype, it may either
- * specify incorrect parameter names or not have names at all.
- */
- foreach_iter(exec_list_iterator, iter, parameters) {
- assert(((ir_instruction *) iter.get())->as_variable() != NULL);
-
- iter.remove();
- }
-
- new_params->move_nodes_to(¶meters);
-}
-
-
-ir_function::ir_function(const char *name)
- : name(name)
-{
- /* empty */
-}
-
-
-ir_call *
-ir_call::get_error_instruction(void *ctx)
-{
- ir_call *call = new(ctx) ir_call;
-
- call->type = glsl_type::error_type;
- return call;
-}
-
-void
-visit_exec_list(exec_list *list, ir_visitor *visitor)
-{
- foreach_iter(exec_list_iterator, iter, *list) {
- ((ir_instruction *)iter.get())->accept(visitor);
- }
-}
-
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#pragma once
-#ifndef IR_H
-#define IR_H
-
-#include <cstdio>
-#include <cstdlib>
-
-extern "C" {
-#include <talloc.h>
-}
-
-#include "list.h"
-#include "ir_visitor.h"
-#include "ir_hierarchical_visitor.h"
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#endif
-
-struct ir_program {
- void *bong_hits;
-};
-
-/**
- * Base class of all IR instructions
- */
-class ir_instruction : public exec_node {
-public:
- const struct glsl_type *type;
-
- class ir_constant *constant_expression_value();
-
- /** ir_print_visitor helper for debugging. */
- void print(void) const;
-
- virtual void accept(ir_visitor *) = 0;
- virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
- virtual ir_instruction *clone(struct hash_table *ht) const = 0;
-
- /**
- * \name IR instruction downcast functions
- *
- * These functions either cast the object to a derived class or return
- * \c NULL if the object's type does not match the specified derived class.
- * Additional downcast functions will be added as needed.
- */
- /*@{*/
- virtual class ir_variable * as_variable() { return NULL; }
- virtual class ir_function * as_function() { return NULL; }
- virtual class ir_dereference * as_dereference() { return NULL; }
- virtual class ir_dereference_array * as_dereference_array() { return NULL; }
- virtual class ir_rvalue * as_rvalue() { return NULL; }
- virtual class ir_loop * as_loop() { return NULL; }
- virtual class ir_assignment * as_assignment() { return NULL; }
- virtual class ir_call * as_call() { return NULL; }
- virtual class ir_return * as_return() { return NULL; }
- virtual class ir_if * as_if() { return NULL; }
- virtual class ir_swizzle * as_swizzle() { return NULL; }
- virtual class ir_constant * as_constant() { return NULL; }
- /*@}*/
-
-protected:
- ir_instruction()
- {
- /* empty */
- }
-};
-
-
-class ir_rvalue : public ir_instruction {
-public:
- virtual ir_rvalue * as_rvalue()
- {
- return this;
- }
-
- virtual bool is_lvalue()
- {
- return false;
- }
-
- /**
- * Get the variable that is ultimately referenced by an r-value
- */
- virtual ir_variable *variable_referenced()
- {
- return NULL;
- }
-
-
- /**
- * If an r-value is a reference to a whole variable, get that variable
- *
- * \return
- * Pointer to a variable that is completely dereferenced by the r-value. If
- * the r-value is not a dereference or the dereference does not access the
- * entire variable (i.e., it's just one array element, struct field), \c NULL
- * is returned.
- */
- virtual ir_variable *whole_variable_referenced()
- {
- return NULL;
- }
-
-protected:
- ir_rvalue()
- {
- /* empty */
- }
-};
-
-
-enum ir_variable_mode {
- ir_var_auto = 0,
- ir_var_uniform,
- ir_var_in,
- ir_var_out,
- ir_var_inout
-};
-
-enum ir_variable_interpolation {
- ir_var_smooth = 0,
- ir_var_flat,
- ir_var_noperspective
-};
-
-
-class ir_variable : public ir_instruction {
-public:
- ir_variable(const struct glsl_type *, const char *);
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- virtual ir_variable *as_variable()
- {
- return this;
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
-
- /**
- * Get the string value for the interpolation qualifier
- *
- * \return
- * If none of \c shader_in or \c shader_out is set, an empty string will
- * be returned. Otherwise the string that would be used in a shader to
- * specify \c mode will be returned.
- */
- const char *interpolation_string() const;
-
- /**
- * Calculate the number of slots required to hold this variable
- *
- * This is used to determine how many uniform or varying locations a variable
- * occupies. The count is in units of floating point components.
- */
- unsigned component_slots() const;
-
- const char *name;
-
- /**
- * Highest element accessed with a constant expression array index
- *
- * Not used for non-array variables.
- */
- unsigned max_array_access;
-
- unsigned read_only:1;
- unsigned centroid:1;
- unsigned invariant:1;
- /** If the variable is initialized outside of the scope of the shader */
- unsigned shader_in:1;
- /**
- * If the variable value is later used outside of the scope of the shader.
- */
- unsigned shader_out:1;
-
- unsigned mode:3;
- unsigned interpolation:2;
-
- /**
- * Flag that the whole array is assignable
- *
- * In GLSL 1.20 and later whole arrays are assignable (and comparable for
- * equality). This flag enables this behavior.
- */
- unsigned array_lvalue:1;
-
- /**
- * Storage location of the base of this variable
- *
- * The precise meaning of this field depends on the nature of the variable.
- *
- * - Vertex shader input: one of the values from \c gl_vert_attrib.
- * - Vertex shader output: one of the values from \c gl_vert_result.
- * - Fragment shader input: one of the values from \c gl_frag_attrib.
- * - Fragment shader output: one of the values from \c gl_frag_result.
- * - Uniforms: Per-stage uniform slot number.
- * - Other: This field is not currently used.
- *
- * If the variable is a uniform, shader input, or shader output, and the
- * slot has not been assigned, the value will be -1.
- */
- int location;
-
- /**
- * Emit a warning if this variable is accessed.
- */
- const char *warn_extension;
-
- /**
- * Value assigned in the initializer of a variable declared "const"
- */
- ir_constant *constant_value;
-};
-
-
-/*@{*/
-/**
- * The representation of a function instance; may be the full definition or
- * simply a prototype.
- */
-class ir_function_signature : public ir_instruction {
- /* An ir_function_signature will be part of the list of signatures in
- * an ir_function.
- */
-public:
- ir_function_signature(const glsl_type *return_type);
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- /**
- * Get the name of the function for which this is a signature
- */
- const char *function_name() const;
-
- /**
- * Check whether the qualifiers match between this signature's parameters
- * and the supplied parameter list. If not, returns the name of the first
- * parameter with mismatched qualifiers (for use in error messages).
- */
- const char *qualifiers_match(exec_list *params);
-
- /**
- * Replace the current parameter list with the given one. This is useful
- * if the current information came from a prototype, and either has invalid
- * or missing parameter names.
- */
- void replace_parameters(exec_list *new_params);
-
- /**
- * Function return type.
- *
- * \note This discards the optional precision qualifier.
- */
- const struct glsl_type *return_type;
-
- /**
- * List of ir_variable of function parameters.
- *
- * This represents the storage. The paramaters passed in a particular
- * call will be in ir_call::actual_paramaters.
- */
- struct exec_list parameters;
-
- /** Whether or not this function has a body (which may be empty). */
- unsigned is_defined:1;
-
- /** Body of instructions in the function. */
- struct exec_list body;
-
-private:
- /** Function of which this signature is one overload. */
- class ir_function *function;
-
- friend class ir_function;
-};
-
-
-/**
- * Header for tracking multiple overloaded functions with the same name.
- * Contains a list of ir_function_signatures representing each of the
- * actual functions.
- */
-class ir_function : public ir_instruction {
-public:
- ir_function(const char *name);
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- virtual ir_function *as_function()
- {
- return this;
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- void add_signature(ir_function_signature *sig)
- {
- sig->function = this;
- signatures.push_tail(sig);
- }
-
- /**
- * Get an iterator for the set of function signatures
- */
- exec_list_iterator iterator()
- {
- return signatures.iterator();
- }
-
- /**
- * Find a signature that matches a set of actual parameters, taking implicit
- * conversions into account.
- */
- const ir_function_signature *matching_signature(exec_list *actual_param);
-
- /**
- * Find a signature that exactly matches a set of actual parameters without
- * any implicit type conversions.
- */
- ir_function_signature *exact_matching_signature(exec_list *actual_ps);
-
- /**
- * Name of the function.
- */
- const char *name;
-
-private:
- /**
- * List of ir_function_signature for each overloaded function with this name.
- */
- struct exec_list signatures;
-};
-
-inline const char *ir_function_signature::function_name() const
-{
- return function->name;
-}
-/*@}*/
-
-
-/**
- * IR instruction representing high-level if-statements
- */
-class ir_if : public ir_instruction {
-public:
- ir_if(ir_rvalue *condition)
- : condition(condition)
- {
- /* empty */
- }
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- virtual ir_if *as_if()
- {
- return this;
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- ir_rvalue *condition;
- /** List of ir_instruction for the body of the then branch */
- exec_list then_instructions;
- /** List of ir_instruction for the body of the else branch */
- exec_list else_instructions;
-};
-
-
-/**
- * IR instruction representing a high-level loop structure.
- */
-class ir_loop : public ir_instruction {
-public:
- ir_loop() : from(NULL), to(NULL), increment(NULL), counter(NULL)
- {
- /* empty */
- }
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- virtual ir_loop *as_loop()
- {
- return this;
- }
-
- /**
- * Get an iterator for the instructions of the loop body
- */
- exec_list_iterator iterator()
- {
- return body_instructions.iterator();
- }
-
- /** List of ir_instruction that make up the body of the loop. */
- exec_list body_instructions;
-
- /**
- * \name Loop counter and controls
- */
- /*@{*/
- ir_rvalue *from;
- ir_rvalue *to;
- ir_rvalue *increment;
- ir_variable *counter;
- /*@}*/
-};
-
-
-class ir_assignment : public ir_rvalue {
-public:
- ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- virtual ir_assignment * as_assignment()
- {
- return this;
- }
-
- /**
- * Left-hand side of the assignment.
- */
- ir_rvalue *lhs;
-
- /**
- * Value being assigned
- */
- ir_rvalue *rhs;
-
- /**
- * Optional condition for the assignment.
- */
- ir_rvalue *condition;
-};
-
-/* Update ir_expression::num_operands() and operator_strs when
- * updating this list.
- */
-enum ir_expression_operation {
- ir_unop_bit_not,
- ir_unop_logic_not,
- ir_unop_neg,
- ir_unop_abs,
- ir_unop_sign,
- ir_unop_rcp,
- ir_unop_rsq,
- ir_unop_sqrt,
- ir_unop_exp,
- ir_unop_log,
- ir_unop_exp2,
- ir_unop_log2,
- ir_unop_f2i, /**< Float-to-integer conversion. */
- ir_unop_i2f, /**< Integer-to-float conversion. */
- ir_unop_f2b, /**< Float-to-boolean conversion */
- ir_unop_b2f, /**< Boolean-to-float conversion */
- ir_unop_i2b, /**< int-to-boolean conversion */
- ir_unop_b2i, /**< Boolean-to-int conversion */
- ir_unop_u2f, /**< Unsigned-to-float conversion. */
-
- /**
- * \name Unary floating-point rounding operations.
- */
- /*@{*/
- ir_unop_trunc,
- ir_unop_ceil,
- ir_unop_floor,
- /*@}*/
-
- /**
- * \name Trigonometric operations.
- */
- /*@{*/
- ir_unop_sin,
- ir_unop_cos,
- /*@}*/
-
- /**
- * \name Partial derivatives.
- */
- /*@{*/
- ir_unop_dFdx,
- ir_unop_dFdy,
- /*@}*/
-
- ir_binop_add,
- ir_binop_sub,
- ir_binop_mul,
- ir_binop_div,
- ir_binop_mod,
-
- /**
- * \name Binary comparison operators
- */
- /*@{*/
- ir_binop_less,
- ir_binop_greater,
- ir_binop_lequal,
- ir_binop_gequal,
- ir_binop_equal,
- ir_binop_nequal,
- /*@}*/
-
- /**
- * \name Bit-wise binary operations.
- */
- /*@{*/
- ir_binop_lshift,
- ir_binop_rshift,
- ir_binop_bit_and,
- ir_binop_bit_xor,
- ir_binop_bit_or,
- /*@}*/
-
- ir_binop_logic_and,
- ir_binop_logic_xor,
- ir_binop_logic_or,
-
- ir_binop_dot,
- ir_binop_min,
- ir_binop_max,
-
- ir_binop_pow
-};
-
-class ir_expression : public ir_rvalue {
-public:
- ir_expression(int op, const struct glsl_type *type,
- ir_rvalue *, ir_rvalue *);
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- static unsigned int get_num_operands(ir_expression_operation);
- unsigned int get_num_operands() const
- {
- return get_num_operands(operation);
- }
-
- /**
- * Return a string representing this expression's operator.
- */
- const char *operator_string();
-
- /**
- * Do a reverse-lookup to translate the given string into an operator.
- */
- static ir_expression_operation get_operator(const char *);
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- ir_expression_operation operation;
- ir_rvalue *operands[2];
-};
-
-
-/**
- * IR instruction representing a function call
- */
-class ir_call : public ir_rvalue {
-public:
- ir_call(const ir_function_signature *callee, exec_list *actual_parameters)
- : callee(callee)
- {
- assert(callee->return_type != NULL);
- type = callee->return_type;
- actual_parameters->move_nodes_to(& this->actual_parameters);
- }
-
- virtual ir_instruction *clone(struct hash_table *ht) const;
-
- virtual ir_call *as_call()
- {
- return this;
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- /**
- * Get a generic ir_call object when an error occurs
- *
- * Any allocation will be performed with 'ctx' as talloc owner.
- */
- static ir_call *get_error_instruction(void *ctx);
-
- /**
- * Get an iterator for the set of acutal parameters
- */
- exec_list_iterator iterator()
- {
- return actual_parameters.iterator();
- }
-
- /**
- * Get the name of the function being called.
- */
- const char *callee_name() const
- {
- return callee->function_name();
- }
-
- const ir_function_signature *get_callee()
- {
- return callee;
- }
-
- /**
- * Generates an inline version of the function before @ir,
- * returning the return value of the function.
- */
- ir_rvalue *generate_inline(ir_instruction *ir);
-
-private:
- ir_call()
- : callee(NULL)
- {
- /* empty */
- }
-
- const ir_function_signature *callee;
-
- /* List of ir_rvalue of paramaters passed in this call. */
- exec_list actual_parameters;
-};
-
-
-/**
- * \name Jump-like IR instructions.
- *
- * These include \c break, \c continue, \c return, and \c discard.
- */
-/*@{*/
-class ir_jump : public ir_instruction {
-protected:
- ir_jump()
- {
- /* empty */
- }
-};
-
-class ir_return : public ir_jump {
-public:
- ir_return()
- : value(NULL)
- {
- /* empty */
- }
-
- ir_return(ir_rvalue *value)
- : value(value)
- {
- /* empty */
- }
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- virtual ir_return *as_return()
- {
- return this;
- }
-
- ir_rvalue *get_value() const
- {
- return value;
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- ir_rvalue *value;
-};
-
-
-/**
- * Jump instructions used inside loops
- *
- * These include \c break and \c continue. The \c break within a loop is
- * different from the \c break within a switch-statement.
- *
- * \sa ir_switch_jump
- */
-class ir_loop_jump : public ir_jump {
-public:
- enum jump_mode {
- jump_break,
- jump_continue
- };
-
- ir_loop_jump(jump_mode mode)
- {
- this->mode = mode;
- this->loop = loop;
- }
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- bool is_break() const
- {
- return mode == jump_break;
- }
-
- bool is_continue() const
- {
- return mode == jump_continue;
- }
-
- /** Mode selector for the jump instruction. */
- enum jump_mode mode;
-private:
- /** Loop containing this break instruction. */
- ir_loop *loop;
-};
-/*@}*/
-
-
-/**
- * Texture sampling opcodes used in ir_texture
- */
-enum ir_texture_opcode {
- ir_tex, /* Regular texture look-up */
- ir_txb, /* Texture look-up with LOD bias */
- ir_txl, /* Texture look-up with explicit LOD */
- ir_txd, /* Texture look-up with partial derivatvies */
- ir_txf /* Texel fetch with explicit LOD */
-};
-
-
-/**
- * IR instruction to sample a texture
- *
- * The specific form of the IR instruction depends on the \c mode value
- * selected from \c ir_texture_opcodes. In the printed IR, these will
- * appear as:
- *
- * Texel offset
- * | Projection divisor
- * | | Shadow comparitor
- * | | |
- * v v v
- * (tex (sampler) (coordinate) (0 0 0) (1) ( ))
- * (txb (sampler) (coordinate) (0 0 0) (1) ( ) (bias))
- * (txl (sampler) (coordinate) (0 0 0) (1) ( ) (lod))
- * (txd (sampler) (coordinate) (0 0 0) (1) ( ) (dPdx dPdy))
- * (txf (sampler) (coordinate) (0 0 0) (lod))
- */
-class ir_texture : public ir_rvalue {
-public:
- ir_texture(enum ir_texture_opcode op)
- : op(op), projector(NULL), shadow_comparitor(NULL)
- {
- /* empty */
- }
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- /**
- * Return a string representing the ir_texture_opcode.
- */
- const char *opcode_string();
-
- /** Set the sampler and infer the type. */
- void set_sampler(ir_dereference *sampler);
-
- /**
- * Do a reverse-lookup to translate a string into an ir_texture_opcode.
- */
- static ir_texture_opcode get_opcode(const char *);
-
- enum ir_texture_opcode op;
-
- /** Sampler to use for the texture access. */
- ir_dereference *sampler;
-
- /** Texture coordinate to sample */
- ir_rvalue *coordinate;
-
- /**
- * Value used for projective divide.
- *
- * If there is no projective divide (the common case), this will be
- * \c NULL. Optimization passes should check for this to point to a constant
- * of 1.0 and replace that with \c NULL.
- */
- ir_rvalue *projector;
-
- /**
- * Coordinate used for comparison on shadow look-ups.
- *
- * If there is no shadow comparison, this will be \c NULL. For the
- * \c ir_txf opcode, this *must* be \c NULL.
- */
- ir_rvalue *shadow_comparitor;
-
- /** Explicit texel offsets. */
- signed char offsets[3];
-
- union {
- ir_rvalue *lod; /**< Floating point LOD */
- ir_rvalue *bias; /**< Floating point LOD bias */
- struct {
- ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */
- ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */
- } grad;
- } lod_info;
-};
-
-
-struct ir_swizzle_mask {
- unsigned x:2;
- unsigned y:2;
- unsigned z:2;
- unsigned w:2;
-
- /**
- * Number of components in the swizzle.
- */
- unsigned num_components:3;
-
- /**
- * Does the swizzle contain duplicate components?
- *
- * L-value swizzles cannot contain duplicate components.
- */
- unsigned has_duplicates:1;
-};
-
-
-class ir_swizzle : public ir_rvalue {
-public:
- ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
- unsigned count);
- ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- virtual ir_swizzle *as_swizzle()
- {
- return this;
- }
-
- /**
- * Construct an ir_swizzle from the textual representation. Can fail.
- */
- static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length);
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- bool is_lvalue()
- {
- return val->is_lvalue() && !mask.has_duplicates;
- }
-
- /**
- * Get the variable that is ultimately referenced by an r-value
- */
- virtual ir_variable *variable_referenced();
-
- ir_rvalue *val;
- ir_swizzle_mask mask;
-};
-
-
-class ir_dereference : public ir_rvalue {
-public:
- virtual ir_dereference *as_dereference()
- {
- return this;
- }
-
- bool is_lvalue();
-
- /**
- * Get the variable that is ultimately referenced by an r-value
- */
- virtual ir_variable *variable_referenced() = 0;
-};
-
-
-class ir_dereference_variable : public ir_dereference {
-public:
- ir_dereference_variable(ir_variable *var);
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- /**
- * Get the variable that is ultimately referenced by an r-value
- */
- virtual ir_variable *variable_referenced()
- {
- return this->var;
- }
-
- virtual ir_variable *whole_variable_referenced()
- {
- /* ir_dereference_variable objects always dereference the entire
- * variable. However, if this dereference is dereferenced by anything
- * else, the complete deferefernce chain is not a whole-variable
- * dereference. This method should only be called on the top most
- * ir_rvalue in a dereference chain.
- */
- return this->var;
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- /**
- * Object being dereferenced.
- */
- ir_variable *var;
-};
-
-
-class ir_dereference_array : public ir_dereference {
-public:
- ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index);
-
- ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- virtual ir_dereference_array *as_dereference_array()
- {
- return this;
- }
-
- /**
- * Get the variable that is ultimately referenced by an r-value
- */
- virtual ir_variable *variable_referenced()
- {
- return this->array->variable_referenced();
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- ir_rvalue *array;
- ir_rvalue *array_index;
-
-private:
- void set_array(ir_rvalue *value);
-};
-
-
-class ir_dereference_record : public ir_dereference {
-public:
- ir_dereference_record(ir_rvalue *value, const char *field);
-
- ir_dereference_record(ir_variable *var, const char *field);
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- /**
- * Get the variable that is ultimately referenced by an r-value
- */
- virtual ir_variable *variable_referenced()
- {
- return this->record->variable_referenced();
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- ir_rvalue *record;
- const char *field;
-};
-
-
-/**
- * Data stored in an ir_constant
- */
-union ir_constant_data {
- unsigned u[16];
- int i[16];
- float f[16];
- bool b[16];
-};
-
-
-class ir_constant : public ir_rvalue {
-public:
- ir_constant(const struct glsl_type *type, const ir_constant_data *data);
- ir_constant(bool b);
- ir_constant(unsigned int u);
- ir_constant(int i);
- ir_constant(float f);
-
- /**
- * Construct an ir_constant from a list of ir_constant values
- */
- ir_constant(const struct glsl_type *type, exec_list *values);
-
- /**
- * Construct an ir_constant from a scalar component of another ir_constant
- *
- * The new \c ir_constant inherits the type of the component from the
- * source constant.
- *
- * \note
- * In the case of a matrix constant, the new constant is a scalar, \b not
- * a vector.
- */
- ir_constant(const ir_constant *c, unsigned i);
-
- virtual ir_instruction *clone(struct hash_table *) const;
-
- virtual ir_constant *as_constant()
- {
- return this;
- }
-
- virtual void accept(ir_visitor *v)
- {
- v->visit(this);
- }
-
- virtual ir_visitor_status accept(ir_hierarchical_visitor *);
-
- /**
- * Get a particular component of a constant as a specific type
- *
- * This is useful, for example, to get a value from an integer constant
- * as a float or bool. This appears frequently when constructors are
- * called with all constant parameters.
- */
- /*@{*/
- bool get_bool_component(unsigned i) const;
- float get_float_component(unsigned i) const;
- int get_int_component(unsigned i) const;
- unsigned get_uint_component(unsigned i) const;
- /*@}*/
-
- ir_constant *get_record_field(const char *name);
-
- /**
- * Determine whether a constant has the same value as another constant
- */
- bool has_value(const ir_constant *) const;
-
- /**
- * Value of the constant.
- *
- * The field used to back the values supplied by the constant is determined
- * by the type associated with the \c ir_instruction. Constants may be
- * scalars, vectors, or matrices.
- */
- union ir_constant_data value;
-
- exec_list components;
-
-private:
- /**
- * Parameterless constructor only used by the clone method
- */
- ir_constant(void);
-};
-
-void
-visit_exec_list(exec_list *list, ir_visitor *visitor);
-
-void validate_ir_tree(exec_list *instructions);
-
-extern void
-_mesa_glsl_initialize_variables(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
-extern void
-_mesa_glsl_initialize_functions(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
-#endif /* IR_H */
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_basic_block.cpp
- *
- * Basic block analysis of instruction streams.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_basic_block.h"
-#include "glsl_types.h"
-
-class ir_has_call_visitor : public ir_hierarchical_visitor {
-public:
- ir_has_call_visitor()
- {
- has_call = false;
- }
-
- virtual ir_visitor_status visit_enter(ir_call *ir)
- {
- (void) ir;
- has_call = true;
- return visit_stop;
- }
-
- bool has_call;
-};
-
-/**
- * Calls a user function for every basic block in the instruction stream.
- *
- * Basic block analysis is pretty easy in our IR thanks to the lack of
- * unstructured control flow. We've got:
- *
- * ir_loop (for () {}, while () {}, do {} while ())
- * ir_loop_jump (
- * ir_if () {}
- * ir_return
- * ir_call()
- *
- * Note that the basic blocks returned by this don't encompass all
- * operations performed by the program -- for example, if conditions
- * don't get returned, nor do the assignments that will be generated
- * for ir_call parameters.
- */
-void call_for_basic_blocks(exec_list *instructions,
- void (*callback)(ir_instruction *first,
- ir_instruction *last,
- void *data),
- void *data)
-{
- ir_instruction *leader = NULL;
- ir_instruction *last = NULL;
-
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- ir_if *ir_if;
- ir_loop *ir_loop;
- ir_function *ir_function;
-
- if (!leader)
- leader = ir;
-
- if ((ir_if = ir->as_if())) {
- callback(leader, ir, data);
- leader = NULL;
-
- call_for_basic_blocks(&ir_if->then_instructions, callback, data);
- call_for_basic_blocks(&ir_if->else_instructions, callback, data);
- } else if ((ir_loop = ir->as_loop())) {
- callback(leader, ir, data);
- leader = NULL;
- call_for_basic_blocks(&ir_loop->body_instructions, callback, data);
- } else if (ir->as_return() || ir->as_call()) {
- callback(leader, ir, data);
- leader = NULL;
- } else if ((ir_function = ir->as_function())) {
- /* A function definition doesn't interrupt our basic block
- * since execution doesn't go into it. We should process the
- * bodies of its signatures for BBs, though.
- *
- * Note that we miss an opportunity for producing more
- * maximal BBs between the instructions that precede main()
- * and the body of main(). Perhaps those instructions ought
- * to live inside of main().
- */
- foreach_iter(exec_list_iterator, fun_iter, *ir_function) {
- ir_function_signature *ir_sig;
-
- ir_sig = (ir_function_signature *)fun_iter.get();
-
- call_for_basic_blocks(&ir_sig->body, callback, data);
- }
- } else if (ir->as_assignment()) {
- ir_has_call_visitor v;
-
- /* If there's a call in the expression tree being assigned,
- * then that ends the BB too.
- *
- * The assumption is that any consumer of the basic block
- * walker is fine with the fact that the call is somewhere in
- * the tree even if portions of the tree may be evaluated
- * after the call.
- *
- * A consumer that has an issue with this could not process
- * the last instruction of the basic block. If doing so,
- * expression flattener may be useful before using the basic
- * block finder to get more maximal basic blocks out.
- */
- ir->accept(&v);
- if (v.has_call) {
- callback(leader, ir, data);
- leader = NULL;
- }
- }
- last = ir;
- }
- if (leader) {
- callback(leader, last, data);
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-
-void call_for_basic_blocks(exec_list *instructions,
- void (*callback)(ir_instruction *first,
- ir_instruction *last,
- void *data),
- void *data);
+++ /dev/null
-/*
- * 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 <string.h>
-#include "ir.h"
-#include "glsl_types.h"
-#include "hash_table.h"
-
-/**
- * Duplicate an IR variable
- *
- * \note
- * This will probably be made \c virtual and moved to the base class
- * eventually.
- */
-ir_instruction *
-ir_variable::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- ir_variable *var = new(ctx) ir_variable(type, name);
-
- var->max_array_access = this->max_array_access;
- var->read_only = this->read_only;
- var->centroid = this->centroid;
- var->invariant = this->invariant;
- var->mode = this->mode;
- var->interpolation = this->interpolation;
-
- if (ht) {
- hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this));
- }
-
- return var;
-}
-
-ir_instruction *
-ir_swizzle::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- return new(ctx) ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask);
-}
-
-ir_instruction *
-ir_return::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- ir_rvalue *new_value = NULL;
-
- if (this->value)
- new_value = (ir_rvalue *)this->value->clone(ht);
-
- return new(ctx) ir_return(new_value);
-}
-
-ir_instruction *
-ir_loop_jump::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- (void)ht;
-
- return new(ctx) ir_loop_jump(this->mode);
-}
-
-ir_instruction *
-ir_if::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- ir_if *new_if = new(ctx) ir_if((ir_rvalue *)this->condition->clone(ht));
-
- foreach_iter(exec_list_iterator, iter, this->then_instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- new_if->then_instructions.push_tail(ir->clone(ht));
- }
-
- foreach_iter(exec_list_iterator, iter, this->else_instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- new_if->else_instructions.push_tail(ir->clone(ht));
- }
-
- return new_if;
-}
-
-ir_instruction *
-ir_loop::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- ir_loop *new_loop = new(ctx) ir_loop();
-
- if (this->from)
- new_loop->from = (ir_rvalue *)this->from->clone(ht);
- if (this->to)
- new_loop->to = (ir_rvalue *)this->to->clone(ht);
- if (this->increment)
- new_loop->increment = (ir_rvalue *)this->increment->clone(ht);
- new_loop->counter = counter;
-
- foreach_iter(exec_list_iterator, iter, this->body_instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- new_loop->body_instructions.push_tail(ir->clone(ht));
- }
-
- return new_loop;
-}
-
-ir_instruction *
-ir_call::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- exec_list new_parameters;
-
- foreach_iter(exec_list_iterator, iter, this->actual_parameters) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- new_parameters.push_tail(ir->clone(ht));
- }
-
- return new(ctx) ir_call(this->callee, &new_parameters);
-}
-
-ir_instruction *
-ir_expression::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- ir_rvalue *op[2] = {NULL, NULL};
- unsigned int i;
-
- for (i = 0; i < get_num_operands(); i++) {
- op[i] = (ir_rvalue *)this->operands[i]->clone(ht);
- }
-
- return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]);
-}
-
-ir_instruction *
-ir_dereference_variable::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- ir_variable *new_var;
-
- if (ht) {
- new_var = (ir_variable *)hash_table_find(ht, this->var);
- if (!new_var)
- new_var = this->var;
- } else {
- new_var = this->var;
- }
-
- return new(ctx) ir_dereference_variable(new_var);
-}
-
-ir_instruction *
-ir_dereference_array::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- return new(ctx) ir_dereference_array((ir_rvalue *)this->array->clone(ht),
- (ir_rvalue *)this->array_index->clone(ht));
-}
-
-ir_instruction *
-ir_dereference_record::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- return new(ctx) ir_dereference_record((ir_rvalue *)this->record->clone(ht),
- this->field);
-}
-
-ir_instruction *
-ir_texture::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- ir_texture *new_tex = new(ctx) ir_texture(this->op);
-
- new_tex->sampler = (ir_dereference *)this->sampler->clone(ht);
- new_tex->coordinate = (ir_rvalue *)this->coordinate->clone(ht);
- if (this->projector)
- new_tex->projector = (ir_rvalue *)this->projector->clone(ht);
- if (this->shadow_comparitor) {
- new_tex->shadow_comparitor =
- (ir_rvalue *)this->shadow_comparitor->clone(ht);
- }
-
- for (int i = 0; i < 3; i++)
- new_tex->offsets[i] = this->offsets[i];
-
- switch (this->op) {
- case ir_tex:
- break;
- case ir_txb:
- new_tex->lod_info.bias = (ir_rvalue *)this->lod_info.bias->clone(ht);
- break;
- case ir_txl:
- case ir_txf:
- new_tex->lod_info.lod = (ir_rvalue *)this->lod_info.lod->clone(ht);
- break;
- case ir_txd:
- new_tex->lod_info.grad.dPdx =
- (ir_rvalue *)this->lod_info.grad.dPdx->clone(ht);
- new_tex->lod_info.grad.dPdy =
- (ir_rvalue *)this->lod_info.grad.dPdy->clone(ht);
- break;
- }
-
- return new_tex;
-}
-
-ir_instruction *
-ir_assignment::clone(struct hash_table *ht) const
-{
- ir_rvalue *new_condition = NULL;
-
- if (this->condition)
- new_condition = (ir_rvalue *)this->condition->clone(ht);
-
- void *ctx = talloc_parent(this);
- return new(ctx) ir_assignment((ir_rvalue *)this->lhs->clone(ht),
- (ir_rvalue *)this->rhs->clone(ht),
- new_condition);
-}
-
-ir_instruction *
-ir_function::clone(struct hash_table *ht) const
-{
- (void)ht;
- /* FINISHME */
- abort();
-}
-
-ir_instruction *
-ir_function_signature::clone(struct hash_table *ht) const
-{
- (void)ht;
- /* FINISHME */
- abort();
-}
-
-ir_instruction *
-ir_constant::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
- (void)ht;
-
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_BOOL:
- return new(ctx) ir_constant(this->type, &this->value);
-
- case GLSL_TYPE_STRUCT: {
- ir_constant *c = new(ctx) ir_constant;
-
- c->type = this->type;
- for (exec_node *node = this->components.head
- ; !node->is_tail_sentinal()
- ; node = node->next) {
- ir_constant *const orig = (ir_constant *) node;
-
- c->components.push_tail(orig->clone(NULL));
- }
-
- return c;
- }
-
- default:
- assert(!"Should not get here."); break;
- return NULL;
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_constant_expression.cpp
- * Evaluate and process constant valued expressions
- *
- * In GLSL, constant valued expressions are used in several places. These
- * must be processed and evaluated very early in the compilation process.
- *
- * * Sizes of arrays
- * * Initializers for uniforms
- * * Initializers for \c const variables
- */
-
-#include <math.h>
-#include "ir.h"
-#include "ir_visitor.h"
-#include "glsl_types.h"
-
-/**
- * Visitor class for evaluating constant expressions
- */
-class ir_constant_visitor : public ir_visitor {
-public:
- ir_constant_visitor()
- : value(NULL)
- {
- /* empty */
- }
-
- virtual ~ir_constant_visitor()
- {
- /* empty */
- }
-
- /**
- * \name Visit methods
- *
- * As typical for the visitor pattern, there must be one \c visit method for
- * each concrete subclass of \c ir_instruction. Virtual base classes within
- * the hierarchy should not have \c visit methods.
- */
- /*@{*/
- virtual void visit(ir_variable *);
- virtual void visit(ir_function_signature *);
- virtual void visit(ir_function *);
- virtual void visit(ir_expression *);
- virtual void visit(ir_texture *);
- virtual void visit(ir_swizzle *);
- virtual void visit(ir_dereference_variable *);
- virtual void visit(ir_dereference_array *);
- virtual void visit(ir_dereference_record *);
- virtual void visit(ir_assignment *);
- virtual void visit(ir_constant *);
- virtual void visit(ir_call *);
- virtual void visit(ir_return *);
- virtual void visit(ir_if *);
- virtual void visit(ir_loop *);
- virtual void visit(ir_loop_jump *);
- /*@}*/
-
- /**
- * Value of the constant expression.
- *
- * \note
- * This field will be \c NULL if the expression is not constant valued.
- */
- /* FINIHSME: This cannot hold values for constant arrays or structures. */
- ir_constant *value;
-};
-
-
-ir_constant *
-ir_instruction::constant_expression_value()
-{
- ir_constant_visitor visitor;
-
- this->accept(& visitor);
- return visitor.value;
-}
-
-
-void
-ir_constant_visitor::visit(ir_variable *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_function_signature *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_function *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-void
-ir_constant_visitor::visit(ir_expression *ir)
-{
- value = NULL;
- ir_constant *op[2];
- unsigned int operand, c;
- ir_constant_data data;
-
- for (operand = 0; operand < ir->get_num_operands(); operand++) {
- op[operand] = ir->operands[operand]->constant_expression_value();
- if (!op[operand])
- return;
- }
-
- switch (ir->operation) {
- case ir_unop_logic_not:
- assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
- for (c = 0; c < ir->operands[0]->type->components(); c++)
- data.b[c] = !op[0]->value.b[c];
- break;
-
- case ir_unop_f2i:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.i[c] = op[0]->value.f[c];
- }
- break;
- case ir_unop_i2f:
- assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
- op[0]->type->base_type == GLSL_TYPE_INT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- if (op[0]->type->base_type == GLSL_TYPE_INT)
- data.f[c] = op[0]->value.i[c];
- else
- data.f[c] = op[0]->value.u[c];
- }
- break;
- case ir_unop_b2f:
- assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
- }
- break;
- case ir_unop_f2b:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.b[c] = bool(op[0]->value.f[c]);
- }
- break;
- case ir_unop_b2i:
- assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.u[c] = op[0]->value.b[c] ? 1 : 0;
- }
- break;
- case ir_unop_i2b:
- assert(op[0]->type->is_integer());
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.b[c] = bool(op[0]->value.u[c]);
- }
- break;
-
- case ir_unop_neg:
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->type->base_type) {
- case GLSL_TYPE_UINT:
- data.u[c] = -op[0]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.i[c] = -op[0]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.f[c] = -op[0]->value.f[c];
- break;
- default:
- assert(0);
- }
- }
- break;
-
- case ir_unop_abs:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->type->base_type) {
- case GLSL_TYPE_UINT:
- data.u[c] = op[0]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.i[c] = op[0]->value.i[c];
- if (data.i[c] < 0)
- data.i[c] = -data.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.f[c] = fabs(op[0]->value.f[c]);
- break;
- default:
- assert(0);
- }
- }
- break;
-
- case ir_unop_rcp:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->type->base_type) {
- case GLSL_TYPE_UINT:
- if (op[0]->value.u[c] != 0.0)
- data.u[c] = 1 / op[0]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- if (op[0]->value.i[c] != 0.0)
- data.i[c] = 1 / op[0]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- if (op[0]->value.f[c] != 0.0)
- data.f[c] = 1.0 / op[0]->value.f[c];
- break;
- default:
- assert(0);
- }
- }
- break;
-
- case ir_unop_rsq:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
- }
- break;
-
- case ir_unop_sqrt:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.f[c] = sqrtf(op[0]->value.f[c]);
- }
- break;
-
- case ir_unop_exp:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.f[c] = expf(op[0]->value.f[c]);
- }
- break;
-
- case ir_unop_log:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.f[c] = logf(op[0]->value.f[c]);
- }
- break;
-
- case ir_unop_dFdx:
- case ir_unop_dFdy:
- assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- data.f[c] = 0.0;
- }
- break;
-
- case ir_binop_add:
- if (ir->operands[0]->type == ir->operands[1]->type) {
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.u[c] = op[0]->value.u[c] + op[1]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.i[c] = op[0]->value.i[c] + op[1]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.f[c] = op[0]->value.f[c] + op[1]->value.f[c];
- break;
- default:
- assert(0);
- }
- }
- } else
- /* FINISHME: Support operations with non-equal types. */
- return;
-
- break;
- case ir_binop_sub:
- if (ir->operands[0]->type == ir->operands[1]->type) {
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.u[c] = op[0]->value.u[c] - op[1]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.i[c] = op[0]->value.i[c] - op[1]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.f[c] = op[0]->value.f[c] - op[1]->value.f[c];
- break;
- default:
- assert(0);
- }
- }
- } else
- /* FINISHME: Support operations with non-equal types. */
- return;
-
- break;
- case ir_binop_mul:
- if (ir->operands[0]->type == ir->operands[1]->type &&
- !ir->operands[0]->type->is_matrix()) {
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
- break;
- default:
- assert(0);
- }
- }
- } else
- /* FINISHME: Support operations with non-equal types. */
- return;
-
- break;
- case ir_binop_div:
- if (ir->operands[0]->type == ir->operands[1]->type) {
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.u[c] = op[0]->value.u[c] / op[1]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.i[c] = op[0]->value.i[c] / op[1]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.f[c] = op[0]->value.f[c] / op[1]->value.f[c];
- break;
- default:
- assert(0);
- }
- }
- } else
- /* FINISHME: Support operations with non-equal types. */
- return;
-
- break;
- case ir_binop_logic_and:
- assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
- for (c = 0; c < ir->operands[0]->type->components(); c++)
- data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
- break;
- case ir_binop_logic_xor:
- assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
- for (c = 0; c < ir->operands[0]->type->components(); c++)
- data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
- break;
- case ir_binop_logic_or:
- assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
- for (c = 0; c < ir->operands[0]->type->components(); c++)
- data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
- break;
-
- case ir_binop_less:
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
- break;
- case GLSL_TYPE_INT:
- data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
- break;
- case GLSL_TYPE_FLOAT:
- data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
- break;
- default:
- assert(0);
- }
- break;
- case ir_binop_greater:
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
- break;
- case GLSL_TYPE_INT:
- data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
- break;
- case GLSL_TYPE_FLOAT:
- data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
- break;
- default:
- assert(0);
- }
- break;
- case ir_binop_lequal:
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
- break;
- case GLSL_TYPE_INT:
- data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
- break;
- case GLSL_TYPE_FLOAT:
- data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
- break;
- default:
- assert(0);
- }
- break;
- case ir_binop_gequal:
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
- break;
- case GLSL_TYPE_INT:
- data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
- break;
- case GLSL_TYPE_FLOAT:
- data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
- break;
- default:
- assert(0);
- }
- break;
-
- case ir_binop_equal:
- data.b[0] = true;
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
- break;
- case GLSL_TYPE_BOOL:
- data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
- break;
- default:
- assert(0);
- }
- }
- break;
- case ir_binop_nequal:
- data.b[0] = false;
- for (c = 0; c < ir->operands[0]->type->components(); c++) {
- switch (ir->operands[0]->type->base_type) {
- case GLSL_TYPE_UINT:
- data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
- break;
- case GLSL_TYPE_INT:
- data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
- break;
- case GLSL_TYPE_FLOAT:
- data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
- break;
- case GLSL_TYPE_BOOL:
- data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
- break;
- default:
- assert(0);
- }
- }
- break;
-
- default:
- /* FINISHME: Should handle all expression types. */
- return;
- }
-
- void *ctx = talloc_parent(ir);
- this->value = new(ctx) ir_constant(ir->type, &data);
-}
-
-
-void
-ir_constant_visitor::visit(ir_texture *ir)
-{
- // FINISHME: Do stuff with texture lookups
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_swizzle *ir)
-{
- ir_constant *v = ir->val->constant_expression_value();
-
- this->value = NULL;
-
- if (v != NULL) {
- ir_constant_data data;
-
- const unsigned swiz_idx[4] = {
- ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
- };
-
- for (unsigned i = 0; i < ir->mask.num_components; i++) {
- switch (v->type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
- case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
- case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
- default: assert(!"Should not get here."); break;
- }
- }
-
- void *ctx = talloc_parent(ir);
- this->value = new(ctx) ir_constant(ir->type, &data);
- }
-}
-
-
-void
-ir_constant_visitor::visit(ir_dereference_variable *ir)
-{
- value = NULL;
-
- ir_variable *var = ir->variable_referenced();
- if (var && var->constant_value)
- value = (ir_constant *)var->constant_value->clone(NULL);
-}
-
-
-void
-ir_constant_visitor::visit(ir_dereference_array *ir)
-{
- void *ctx = talloc_parent(ir);
- ir_constant *array = ir->array->constant_expression_value();
- ir_constant *idx = ir->array_index->constant_expression_value();
-
- this->value = NULL;
-
- if ((array != NULL) && (idx != NULL)) {
- if (array->type->is_matrix()) {
- /* Array access of a matrix results in a vector.
- */
- const unsigned column = idx->value.u[0];
-
- const glsl_type *const column_type = array->type->column_type();
-
- /* Offset in the constant matrix to the first element of the column
- * to be extracted.
- */
- const unsigned mat_idx = column * column_type->vector_elements;
-
- ir_constant_data data;
-
- switch (column_type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- for (unsigned i = 0; i < column_type->vector_elements; i++)
- data.u[i] = array->value.u[mat_idx + i];
-
- break;
-
- case GLSL_TYPE_FLOAT:
- for (unsigned i = 0; i < column_type->vector_elements; i++)
- data.f[i] = array->value.f[mat_idx + i];
-
- break;
-
- default:
- assert(!"Should not get here.");
- break;
- }
-
- this->value = new(ctx) ir_constant(column_type, &data);
- } else if (array->type->is_vector()) {
- const unsigned component = idx->value.u[0];
-
- this->value = new(ctx) ir_constant(array, component);
- } else {
- /* FINISHME: Handle access of constant arrays. */
- }
- }
-}
-
-
-void
-ir_constant_visitor::visit(ir_dereference_record *ir)
-{
- ir_constant *v = ir->record->constant_expression_value();
-
- this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_assignment *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_constant *ir)
-{
- value = ir;
-}
-
-
-void
-ir_constant_visitor::visit(ir_call *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_return *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_if *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_loop *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_loop_jump *ir)
-{
- (void) ir;
- value = NULL;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_constant_folding.cpp
- * Replace constant-valued expressions with references to constant values.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_optimization.h"
-#include "glsl_types.h"
-
-/**
- * Visitor class for replacing expressions with ir_constant values.
- */
-
-class ir_constant_folding_visitor : public ir_visitor {
-public:
- ir_constant_folding_visitor()
- {
- /* empty */
- }
-
- virtual ~ir_constant_folding_visitor()
- {
- /* empty */
- }
-
- /**
- * \name Visit methods
- *
- * As typical for the visitor pattern, there must be one \c visit method for
- * each concrete subclass of \c ir_instruction. Virtual base classes within
- * the hierarchy should not have \c visit methods.
- */
- /*@{*/
- virtual void visit(ir_variable *);
- virtual void visit(ir_function_signature *);
- virtual void visit(ir_function *);
- virtual void visit(ir_expression *);
- virtual void visit(ir_texture *);
- virtual void visit(ir_swizzle *);
- virtual void visit(ir_dereference_variable *);
- virtual void visit(ir_dereference_array *);
- virtual void visit(ir_dereference_record *);
- virtual void visit(ir_assignment *);
- virtual void visit(ir_constant *);
- virtual void visit(ir_call *);
- virtual void visit(ir_return *);
- virtual void visit(ir_if *);
- virtual void visit(ir_loop *);
- virtual void visit(ir_loop_jump *);
- /*@}*/
-};
-
-void
-ir_constant_folding_visitor::visit(ir_variable *ir)
-{
- (void) ir;
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_function_signature *ir)
-{
- visit_exec_list(&ir->body, this);
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_function *ir)
-{
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_function_signature *const sig = (ir_function_signature *) iter.get();
- sig->accept(this);
- }
-}
-
-void
-ir_constant_folding_visitor::visit(ir_expression *ir)
-{
- ir_constant *op[2];
- unsigned int operand;
-
- for (operand = 0; operand < ir->get_num_operands(); operand++) {
- op[operand] = ir->operands[operand]->constant_expression_value();
- if (op[operand]) {
- ir->operands[operand] = op[operand];
- } else {
- ir->operands[operand]->accept(this);
- }
- }
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_texture *ir)
-{
- // FINISHME: Do stuff with texture lookups
- (void) ir;
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_swizzle *ir)
-{
- ir->val->accept(this);
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_dereference_variable *ir)
-{
- (void) ir;
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_dereference_array *ir)
-{
- ir_constant *const_val =
- ir->array_index->constant_expression_value();
-
- if (const_val)
- ir->array_index = const_val;
- else
- ir->array_index->accept(this);
-
- ir->array->accept(this);
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_dereference_record *ir)
-{
- ir->record->accept(this);
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_assignment *ir)
-{
- ir_constant *const_val = ir->rhs->constant_expression_value();
- if (const_val)
- ir->rhs = const_val;
- else
- ir->rhs->accept(this);
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_constant *ir)
-{
- (void) ir;
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_call *ir)
-{
- (void) ir;
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_return *ir)
-{
- (void) ir;
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_if *ir)
-{
- ir_constant *const_val = ir->condition->constant_expression_value();
- if (const_val)
- ir->condition = const_val;
- else
- ir->condition->accept(this);
-
- visit_exec_list(&ir->then_instructions, this);
- visit_exec_list(&ir->else_instructions, this);
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_loop *ir)
-{
- (void) ir;
-}
-
-
-void
-ir_constant_folding_visitor::visit(ir_loop_jump *ir)
-{
- (void) ir;
-}
-
-bool
-do_constant_folding(exec_list *instructions)
-{
- ir_constant_folding_visitor constant_folding;
-
- visit_exec_list(instructions, &constant_folding);
-
- /* FINISHME: Return real progress. */
- return false;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_constant_variable.cpp
- *
- * Marks variables assigned a single constant value over the course
- * of the program as constant.
- *
- * The goal here is to trigger further constant folding and then dead
- * code elimination. This is common with vector/matrix constructors
- * and calls to builtin functions.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_optimization.h"
-#include "glsl_types.h"
-
-struct assignment_entry {
- exec_node link;
- int assignment_count;
- ir_variable *var;
- ir_constant *constval;
-};
-
-class ir_constant_variable_visitor : public ir_hierarchical_visitor {
-public:
- virtual ir_visitor_status visit_enter(ir_assignment *);
-
- exec_list list;
-};
-
-static struct assignment_entry *
-get_assignment_entry(ir_variable *var, exec_list *list)
-{
- struct assignment_entry *entry;
-
- foreach_list_typed(struct assignment_entry, entry, link, list) {
- if (entry->var == var)
- return entry;
- }
-
- entry = (struct assignment_entry *)calloc(1, sizeof(*entry));
- entry->var = var;
- list->push_head(&entry->link);
- return entry;
-}
-
-ir_visitor_status
-ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
-{
- ir_constant *constval;
- struct assignment_entry *entry;
-
- entry = get_assignment_entry(ir->lhs->variable_referenced(), &this->list);
- assert(entry);
- entry->assignment_count++;
-
- /* If it's already constant, don't do the work. */
- if (entry->var->constant_value)
- return visit_continue;
-
- /* OK, now find if we actually have all the right conditions for
- * this to be a constant value assigned to the var.
- */
- if (ir->condition) {
- constval = ir->condition->constant_expression_value();
- if (!constval || !constval->value.b[0])
- return visit_continue;
- }
-
- ir_variable *var = ir->lhs->whole_variable_referenced();
- if (!var)
- return visit_continue;
-
- constval = ir->rhs->constant_expression_value();
- if (!constval)
- return visit_continue;
-
- /* Mark this entry as having a constant assignment (if the
- * assignment count doesn't go >1). do_constant_variable will fix
- * up the variable with the constant value later.
- */
- entry->constval = constval;
-
- return visit_continue;
-}
-
-/**
- * Does a copy propagation pass on the code present in the instruction stream.
- */
-bool
-do_constant_variable(exec_list *instructions)
-{
- bool progress = false;
- ir_constant_variable_visitor v;
-
- v.run(instructions);
-
- while (!v.list.is_empty()) {
-
- struct assignment_entry *entry;
- entry = exec_node_data(struct assignment_entry, v.list.head, link);
-
- if (entry->assignment_count == 1 && entry->constval) {
- entry->var->constant_value = entry->constval;
- progress = true;
- }
- entry->link.remove();
- free(entry);
- }
-
- return progress;
-}
-
-bool
-do_constant_variable_unlinked(exec_list *instructions)
-{
- bool progress = false;
-
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- ir_function *f = ir->as_function();
- if (f) {
- foreach_iter(exec_list_iterator, sigiter, *f) {
- ir_function_signature *sig =
- (ir_function_signature *) sigiter.get();
- if (do_constant_variable(&sig->body))
- progress = true;
- }
- }
- }
-
- return progress;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_copy_propagation.cpp
- *
- * Moves usage of recently-copied variables to the previous copy of
- * the variable within basic blocks.
- *
- * This should reduce the number of MOV instructions in the generated
- * programs unless copy propagation is also done on the LIR, and may
- * help anyway by triggering other optimizations that live in the HIR.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_basic_block.h"
-#include "ir_optimization.h"
-#include "glsl_types.h"
-
-class acp_entry : public exec_node
-{
-public:
- acp_entry(ir_variable *lhs, ir_variable *rhs)
- {
- assert(lhs);
- assert(rhs);
- this->lhs = lhs;
- this->rhs = rhs;
- }
-
- ir_variable *lhs;
- ir_variable *rhs;
-};
-
-class ir_copy_propagation_visitor : public ir_hierarchical_visitor {
-public:
- ir_copy_propagation_visitor(exec_list *acp)
- {
- progress = false;
- in_lhs = false;
- this->acp = acp;
- }
-
- virtual ir_visitor_status visit(class ir_dereference_variable *);
- virtual ir_visitor_status visit_enter(class ir_loop *);
- virtual ir_visitor_status visit_enter(class ir_function_signature *);
- virtual ir_visitor_status visit_enter(class ir_function *);
- virtual ir_visitor_status visit_enter(class ir_assignment *);
- virtual ir_visitor_status visit_enter(class ir_call *);
- virtual ir_visitor_status visit_enter(class ir_if *);
-
- /** List of acp_entry */
- exec_list *acp;
- bool progress;
-
- /** Currently in the LHS of an assignment? */
- bool in_lhs;
-};
-
-
-ir_visitor_status
-ir_copy_propagation_visitor::visit_enter(ir_loop *ir)
-{
- (void)ir;
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-ir_copy_propagation_visitor::visit_enter(ir_function_signature *ir)
-{
- (void)ir;
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-ir_copy_propagation_visitor::visit_enter(ir_assignment *ir)
-{
- (void) ir;
- this->in_lhs = true;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_copy_propagation_visitor::visit_enter(ir_function *ir)
-{
- (void) ir;
- return visit_continue_with_parent;
-}
-
-/**
- * Replaces dereferences of ACP RHS variables with ACP LHS variables.
- *
- * This is where the actual copy propagation occurs. Note that the
- * rewriting of ir_dereference means that the ir_dereference instance
- * must not be shared by multiple IR operations!
- */
-ir_visitor_status
-ir_copy_propagation_visitor::visit(ir_dereference_variable *ir)
-{
- /* Ignores the LHS. Don't want to rewrite the LHS to point at some
- * other storage!
- */
- if (this->in_lhs) {
- this->in_lhs = false;
- return visit_continue;
- }
-
- ir_variable *var = ir->variable_referenced();
-
- foreach_iter(exec_list_iterator, iter, *this->acp) {
- acp_entry *entry = (acp_entry *)iter.get();
-
- if (var == entry->lhs) {
- ir->var = entry->rhs;
- this->progress = true;
- break;
- }
- }
-
- return visit_continue;
-}
-
-
-ir_visitor_status
-ir_copy_propagation_visitor::visit_enter(ir_call *ir)
-{
- (void)ir;
-
- /* Note, if we were to do copy propagation to parameters of calls, we'd
- * have to be careful about out params.
- */
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_copy_propagation_visitor::visit_enter(ir_if *ir)
-{
- ir->condition->accept(this);
-
- /* Do not traverse into the body of the if-statement since that is a
- * different basic block.
- */
- return visit_continue_with_parent;
-}
-
-static bool
-propagate_copies(ir_instruction *ir, exec_list *acp)
-{
- ir_copy_propagation_visitor v(acp);
-
- ir->accept(&v);
-
- return v.progress;
-}
-
-static void
-kill_invalidated_copies(ir_assignment *ir, exec_list *acp)
-{
- ir_variable *var = ir->lhs->variable_referenced();
- assert(var != NULL);
-
- foreach_iter(exec_list_iterator, iter, *acp) {
- acp_entry *entry = (acp_entry *)iter.get();
-
- if (entry->lhs == var || entry->rhs == var) {
- entry->remove();
- }
- }
-}
-
-/**
- * Adds an entry to the available copy list if it's a plain assignment
- * of a variable to a variable.
- */
-static void
-add_copy(ir_assignment *ir, exec_list *acp)
-{
- void *ctx = talloc_parent(ir);
- acp_entry *entry;
-
- if (ir->condition) {
- ir_constant *condition = ir->condition->as_constant();
- if (!condition || !condition->value.b[0])
- return;
- }
-
- ir_variable *lhs_var = ir->lhs->whole_variable_referenced();
- ir_variable *rhs_var = ir->rhs->whole_variable_referenced();
-
- if ((lhs_var != NULL) && (rhs_var != NULL)) {
- entry = new(ctx) acp_entry(lhs_var, rhs_var);
- acp->push_tail(entry);
- }
-}
-
-static void
-copy_propagation_basic_block(ir_instruction *first,
- ir_instruction *last,
- void *data)
-{
- ir_instruction *ir;
- /* List of avaialble_copy */
- exec_list acp;
- bool *out_progress = (bool *)data;
- bool progress = false;
-
- for (ir = first;; ir = (ir_instruction *)ir->next) {
- ir_assignment *ir_assign = ir->as_assignment();
-
- progress = propagate_copies(ir, &acp) || progress;
-
- if (ir_assign) {
- kill_invalidated_copies(ir_assign, &acp);
-
- add_copy(ir_assign, &acp);
- }
- if (ir == last)
- break;
- }
- *out_progress = progress;
-}
-
-/**
- * Does a copy propagation pass on the code present in the instruction stream.
- */
-bool
-do_copy_propagation(exec_list *instructions)
-{
- bool progress = false;
-
- call_for_basic_blocks(instructions, copy_propagation_basic_block, &progress);
-
- return progress;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_dead_code.cpp
- *
- * Eliminates dead assignments and variable declarations from the code.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_expression_flattening.h"
-#include "glsl_types.h"
-
-class variable_entry : public exec_node
-{
-public:
- variable_entry(ir_variable *var)
- {
- this->var = var;
- assign = NULL;
- referenced_count = 0;
- assigned_count = 0;
- declaration = false;
- }
-
- ir_variable *var; /* The key: the variable's pointer. */
- ir_assignment *assign; /* An assignment to the variable, if any */
-
- /** Number of times the variable is referenced, including assignments. */
- unsigned referenced_count;
-
- /** Number of times the variable is assignmened. */
- unsigned assigned_count;
-
- bool declaration; /* If the variable had a decl in the instruction stream */
-};
-
-class ir_dead_code_visitor : public ir_hierarchical_visitor {
-public:
- virtual ir_visitor_status visit(ir_variable *);
- virtual ir_visitor_status visit(ir_dereference_variable *);
-
- virtual ir_visitor_status visit_enter(ir_function *);
- virtual ir_visitor_status visit_leave(ir_assignment *);
-
- variable_entry *get_variable_entry(ir_variable *var);
-
- bool (*predicate)(ir_instruction *ir);
- ir_instruction *base_ir;
-
- /* List of variable_entry */
- exec_list variable_list;
-};
-
-
-variable_entry *
-ir_dead_code_visitor::get_variable_entry(ir_variable *var)
-{
- assert(var);
- foreach_iter(exec_list_iterator, iter, this->variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
- if (entry->var == var)
- return entry;
- }
-
- void *ctx = talloc_parent(var);
-
- variable_entry *entry = new(ctx) variable_entry(var);
- this->variable_list.push_tail(entry);
- return entry;
-}
-
-
-ir_visitor_status
-ir_dead_code_visitor::visit(ir_variable *ir)
-{
- variable_entry *entry = this->get_variable_entry(ir);
- if (entry)
- entry->declaration = true;
-
- return visit_continue;
-}
-
-
-ir_visitor_status
-ir_dead_code_visitor::visit(ir_dereference_variable *ir)
-{
- ir_variable *const var = ir->variable_referenced();
- variable_entry *entry = this->get_variable_entry(var);
-
- if (entry)
- entry->referenced_count++;
-
- return visit_continue;
-}
-
-
-ir_visitor_status
-ir_dead_code_visitor::visit_enter(ir_function *ir)
-{
- (void) ir;
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_dead_code_visitor::visit_leave(ir_assignment *ir)
-{
- variable_entry *entry;
- entry = this->get_variable_entry(ir->lhs->variable_referenced());
- if (entry) {
- entry->assigned_count++;
- if (entry->assign == NULL)
- entry->assign = ir;
- }
-
- return visit_continue;
-}
-
-
-/**
- * Do a dead code pass over instructions and everything that instructions
- * references.
- *
- * Note that this will remove assignments to globals, so it is not suitable
- * for usage on an unlinked instruction stream.
- */
-bool
-do_dead_code(exec_list *instructions)
-{
- ir_dead_code_visitor v;
- bool progress = false;
-
- v.run(instructions);
-
- foreach_iter(exec_list_iterator, iter, v.variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
-
- /* Since each assignment is a reference, the refereneced count must be
- * greater than or equal to the assignment count. If they are equal,
- * then all of the references are assignments, and the variable is
- * dead.
- *
- * Note that if the variable is neither assigned nor referenced, both
- * counts will be zero and will be caught by the equality test.
- */
- assert(entry->referenced_count >= entry->assigned_count);
-
- if ((entry->referenced_count > entry->assigned_count)
- || !entry->declaration)
- continue;
-
- if (entry->assign) {
- /* Remove a single dead assignment to the variable we found.
- * Don't do so if it's a shader output, though.
- */
- if (!entry->var->shader_out) {
- entry->assign->remove();
- progress = true;
- }
- } else {
- /* If there are no assignments or references to the variable left,
- * then we can remove its declaration.
- */
- entry->var->remove();
- progress = true;
- }
- }
- return progress;
-}
-
-/**
- * Does a dead code pass on the functions present in the instruction stream.
- *
- * This is suitable for use while the program is not linked, as it will
- * ignore variable declarations (and the assignments to them) for variables
- * with global scope.
- */
-bool
-do_dead_code_unlinked(exec_list *instructions)
-{
- bool progress = false;
-
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- ir_function *f = ir->as_function();
- if (f) {
- foreach_iter(exec_list_iterator, sigiter, *f) {
- ir_function_signature *sig =
- (ir_function_signature *) sigiter.get();
- if (do_dead_code(&sig->body))
- progress = true;
- }
- }
- }
-
- return progress;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_dead_code_local.cpp
- *
- * Eliminates local dead assignments from the code.
- *
- * This operates on basic blocks, tracking assignments and finding if
- * they're used before the variable is completely reassigned.
- *
- * Compare this to ir_dead_code.cpp, which operates globally looking
- * for assignments to variables that are never read.
- */
-
-#include "ir.h"
-#include "ir_basic_block.h"
-#include "ir_optimization.h"
-#include "glsl_types.h"
-
-static bool debug = false;
-
-class assignment_entry : public exec_node
-{
-public:
- assignment_entry(ir_variable *lhs, ir_instruction *ir)
- {
- assert(lhs);
- assert(ir);
- this->lhs = lhs;
- this->ir = ir;
- }
-
- ir_variable *lhs;
- ir_instruction *ir;
-};
-
-class kill_for_derefs_visitor : public ir_hierarchical_visitor {
-public:
- kill_for_derefs_visitor(exec_list *assignments)
- {
- this->assignments = assignments;
- }
-
- virtual ir_visitor_status visit(ir_dereference_variable *ir)
- {
- ir_variable *const var = ir->variable_referenced();
-
- foreach_iter(exec_list_iterator, iter, *this->assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
-
- if (entry->lhs == var) {
- if (debug)
- printf("kill %s\n", entry->lhs->name);
- entry->remove();
- }
- }
-
- return visit_continue;
- }
-
-private:
- exec_list *assignments;
-};
-
-class array_index_visit : public ir_hierarchical_visitor {
-public:
- array_index_visit(ir_hierarchical_visitor *v)
- {
- this->visitor = v;
- }
-
- virtual ir_visitor_status visit_enter(class ir_dereference_array *ir)
- {
- ir->array_index->accept(visitor);
- return visit_continue;
- }
-
- static void run(ir_instruction *ir, ir_hierarchical_visitor *v)
- {
- array_index_visit top_visit(v);
- ir->accept(& top_visit);
- }
-
- ir_hierarchical_visitor *visitor;
-};
-
-
-/**
- * Adds an entry to the available copy list if it's a plain assignment
- * of a variable to a variable.
- */
-static bool
-process_assignment(ir_assignment *ir, exec_list *assignments)
-{
- void *ctx = talloc_parent(ir);
- ir_variable *var = NULL;
- bool progress = false;
- kill_for_derefs_visitor v(assignments);
-
- /* Kill assignment entries for things used to produce this assignment. */
- ir->rhs->accept(&v);
- if (ir->condition) {
- ir->condition->accept(&v);
- }
-
- /* Kill assignment enties used as array indices.
- */
- array_index_visit::run(ir->lhs, &v);
- var = ir->lhs->variable_referenced();
- assert(var);
-
- bool always_assign = true;
- if (ir->condition) {
- ir_constant *condition = ir->condition->as_constant();
- if (!condition || !condition->value.b[0])
- always_assign = false;
- }
-
- /* Now, check if we did a whole-variable assignment. */
- if (always_assign && (ir->lhs->whole_variable_referenced() != NULL)) {
- /* We did a whole-variable assignment. So, any instruction in
- * the assignment list with the same LHS is dead.
- */
- if (debug)
- printf("looking for %s to remove\n", var->name);
- foreach_iter(exec_list_iterator, iter, *assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
-
- if (entry->lhs == var) {
- if (debug)
- printf("removing %s\n", var->name);
- entry->ir->remove();
- entry->remove();
- progress = true;
- }
- }
- }
-
- /* Add this instruction to the assignment list. */
- assignment_entry *entry = new(ctx) assignment_entry(var, ir);
- assignments->push_tail(entry);
-
- if (debug) {
- printf("add %s\n", var->name);
-
- printf("current entries\n");
- foreach_iter(exec_list_iterator, iter, *assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
-
- printf(" %s\n", entry->lhs->name);
- }
- }
-
- return progress;
-}
-
-static void
-dead_code_local_basic_block(ir_instruction *first,
- ir_instruction *last,
- void *data)
-{
- ir_instruction *ir, *ir_next;
- /* List of avaialble_copy */
- exec_list assignments;
- bool *out_progress = (bool *)data;
- bool progress = false;
-
- /* Safe looping, since process_assignment */
- for (ir = first, ir_next = (ir_instruction *)first->next;;
- ir = ir_next, ir_next = (ir_instruction *)ir->next) {
- ir_assignment *ir_assign = ir->as_assignment();
-
- if (debug) {
- ir->print();
- printf("\n");
- }
-
- if (ir_assign) {
- progress = process_assignment(ir_assign, &assignments) || progress;
- } else {
- kill_for_derefs_visitor kill(&assignments);
- ir->accept(&kill);
- }
-
- if (ir == last)
- break;
- }
- *out_progress = progress;
-}
-
-/**
- * Does a copy propagation pass on the code present in the instruction stream.
- */
-bool
-do_dead_code_local(exec_list *instructions)
-{
- bool progress = false;
-
- call_for_basic_blocks(instructions, dead_code_local_basic_block, &progress);
-
- return progress;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_expression_flattening.cpp
- *
- * Takes the leaves of expression trees and makes them dereferences of
- * assignments of the leaves to temporaries, according to a predicate.
- *
- * This is used for automatic function inlining, where we want to take
- * an expression containing a call and move the call out to its own
- * assignment so that we can inline it at the appropriate place in the
- * instruction stream.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_expression_flattening.h"
-#include "glsl_types.h"
-
-class ir_expression_flattening_visitor : public ir_hierarchical_visitor {
-public:
- ir_expression_flattening_visitor(ir_instruction *base_ir,
- bool (*predicate)(ir_instruction *ir))
- {
- this->base_ir = base_ir;
- this->predicate = predicate;
- }
-
- virtual ~ir_expression_flattening_visitor()
- {
- /* empty */
- }
-
- virtual ir_visitor_status visit_enter(ir_call *);
- virtual ir_visitor_status visit_enter(ir_return *);
- virtual ir_visitor_status visit_enter(ir_function_signature *);
- virtual ir_visitor_status visit_enter(ir_if *);
- virtual ir_visitor_status visit_enter(ir_loop *);
- virtual ir_visitor_status visit_leave(ir_expression *);
- virtual ir_visitor_status visit_leave(ir_swizzle *);
-
- bool (*predicate)(ir_instruction *ir);
- ir_instruction *base_ir;
-};
-
-void
-do_expression_flattening(exec_list *instructions,
- bool (*predicate)(ir_instruction *ir))
-{
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
-
- ir_expression_flattening_visitor v(ir, predicate);
- ir->accept(&v);
- }
-}
-
-
-static ir_rvalue *
-operand_to_temp(ir_instruction *base_ir, ir_rvalue *ir)
-{
- void *ctx = talloc_parent(base_ir);
- ir_variable *var;
- ir_assignment *assign;
-
- var = new(ctx) ir_variable(ir->type, "flattening_tmp");
- base_ir->insert_before(var);
-
- assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
- ir,
- NULL);
- base_ir->insert_before(assign);
-
- return new(ctx) ir_dereference_variable(var);
-}
-
-ir_visitor_status
-ir_expression_flattening_visitor::visit_enter(ir_function_signature *ir)
-{
- do_expression_flattening(&ir->body, this->predicate);
-
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-ir_expression_flattening_visitor::visit_enter(ir_loop *ir)
-{
- do_expression_flattening(&ir->body_instructions, this->predicate);
-
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-ir_expression_flattening_visitor::visit_enter(ir_if *ir)
-{
- ir->condition->accept(this);
-
- do_expression_flattening(&ir->then_instructions, this->predicate);
- do_expression_flattening(&ir->else_instructions, this->predicate);
-
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-ir_expression_flattening_visitor::visit_leave(ir_expression *ir)
-{
- unsigned int operand;
-
- for (operand = 0; operand < ir->get_num_operands(); operand++) {
- /* If the operand matches the predicate, then we'll assign its
- * value to a temporary and deref the temporary as the operand.
- */
- if (this->predicate(ir->operands[operand])) {
- ir->operands[operand] = operand_to_temp(base_ir,
- ir->operands[operand]);
- }
- }
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_expression_flattening_visitor::visit_leave(ir_swizzle *ir)
-{
- if (this->predicate(ir->val)) {
- ir->val = operand_to_temp(this->base_ir, ir->val);
- }
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_expression_flattening_visitor::visit_enter(ir_call *ir)
-{
- /* FINISHME: Why not process the call parameters? (Same behavior as original
- * FINISHME: code.)
- */
- (void) ir;
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_expression_flattening_visitor::visit_enter(ir_return *ir)
-{
- /* FINISHME: Why not process the return value? (Same behavior as original
- * FINISHME: code.)
- */
- (void) ir;
- return visit_continue_with_parent;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-
-/**
- * \file ir_expression_flattening.h
- *
- * Takes the leaves of expression trees and makes them dereferences of
- * assignments of the leaves to temporaries, according to a predicate.
- *
- * This is used for automatic function inlining, where we want to take
- * an expression containing a call and move the call out to its own
- * assignment so that we can inline it at the appropriate place in the
- * instruction stream.
- */
-
-void do_expression_flattening(exec_list *instructions,
- bool (*predicate)(ir_instruction *ir));
+++ /dev/null
-/*
- * 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 "ir.h"
-
-int
-type_compare(const glsl_type *a, const glsl_type *b)
-{
- /* If the types are the same, they trivially match.
- */
- if (a == b)
- return 0;
-
- switch (a->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_BOOL:
- /* There is no implicit conversion to or from integer types or bool.
- */
- if ((a->is_integer() != b->is_integer())
- || (a->is_boolean() != b->is_boolean()))
- return -1;
-
- /* FALLTHROUGH */
-
- case GLSL_TYPE_FLOAT:
- if ((a->vector_elements != b->vector_elements)
- || (a->matrix_columns != b->matrix_columns))
- return -1;
-
- return 1;
-
- case GLSL_TYPE_SAMPLER:
- case GLSL_TYPE_STRUCT:
- /* Samplers and structures must match exactly.
- */
- return -1;
-
- case GLSL_TYPE_ARRAY:
- if ((b->base_type != GLSL_TYPE_ARRAY)
- || (a->length != b->length))
- return -1;
-
- /* From GLSL 1.50 spec, page 27 (page 33 of the PDF):
- * "There are no implicit array or structure conversions."
- *
- * If the comparison of the array element types detects that a conversion
- * would be required, the array types do not match.
- */
- return (type_compare(a->fields.array, b->fields.array) == 0) ? 0 : -1;
-
- case GLSL_TYPE_FUNCTION:
- case GLSL_TYPE_VOID:
- case GLSL_TYPE_ERROR:
- default:
- /* These are all error conditions. It is invalid for a parameter to
- * a function to be declared as error, void, or a function.
- */
- return -1;
- }
-
- /* This point should be unreachable.
- */
- assert(0);
-}
-
-
-static int
-parameter_lists_match(exec_list *list_a, exec_list *list_b)
-{
- exec_list_iterator iter_a = list_a->iterator();
- exec_list_iterator iter_b = list_b->iterator();
- int total_score = 0;
-
- for (/* empty */ ; iter_a.has_next(); iter_a.next(), iter_b.next()) {
- /* If all of the parameters from the other parameter list have been
- * exhausted, the lists have different length and, by definition,
- * do not match.
- */
- if (!iter_b.has_next())
- return -1;
-
-
- const ir_variable *const param = (ir_variable *) iter_a.get();
- const ir_instruction *const actual = (ir_instruction *) iter_b.get();
-
- /* Determine whether or not the types match. If the types are an
- * exact match, the match score is zero. If the types don't match
- * but the actual parameter can be coerced to the type of the declared
- * parameter, the match score is one.
- */
- int score;
- switch ((enum ir_variable_mode)(param->mode)) {
- case ir_var_auto:
- case ir_var_uniform:
- /* These are all error conditions. It is invalid for a parameter to
- * a function to be declared as auto (not in, out, or inout) or
- * as uniform.
- */
- assert(0);
- return -1;
-
- case ir_var_in:
- score = type_compare(param->type, actual->type);
- break;
-
- case ir_var_out:
- score = type_compare(actual->type, param->type);
- break;
-
- case ir_var_inout:
- /* Since there are no bi-directional automatic conversions (e.g.,
- * there is int -> float but no float -> int), inout parameters must
- * be exact matches.
- */
- score = (type_compare(actual->type, param->type) == 0) ? 0 : -1;
- break;
- }
-
- if (score < 0)
- return -1;
-
- total_score += score;
- }
-
- /* If all of the parameters from the other parameter list have been
- * exhausted, the lists have different length and, by definition, do not
- * match.
- */
- if (iter_b.has_next())
- return -1;
-
- return total_score;
-}
-
-
-const ir_function_signature *
-ir_function::matching_signature(exec_list *actual_parameters)
-{
- ir_function_signature *match = NULL;
-
- foreach_iter(exec_list_iterator, iter, signatures) {
- ir_function_signature *const sig =
- (ir_function_signature *) iter.get();
-
- const int score = parameter_lists_match(& sig->parameters,
- actual_parameters);
-
- if (score == 0)
- return sig;
-
- if (score > 0) {
- if (match != NULL)
- return NULL;
-
- match = sig;
- }
- }
-
- return match;
-}
-
-
-static bool
-parameter_lists_match_exact(exec_list *list_a, exec_list *list_b)
-{
- exec_list_iterator iter_a = list_a->iterator();
- exec_list_iterator iter_b = list_b->iterator();
-
- while (iter_a.has_next() && iter_b.has_next()) {
- ir_variable *a = (ir_variable *)iter_a.get();
- ir_variable *b = (ir_variable *)iter_b.get();
-
- /* If the types of the parameters do not match, the parameters lists
- * are different.
- */
- if (a->type != b->type)
- return false;
-
- iter_a.next();
- iter_b.next();
- }
-
- /* Unless both lists are exhausted, they differ in length and, by
- * definition, do not match.
- */
- if (iter_a.has_next() != iter_b.has_next())
- return false;
-
- return true;
-}
-
-ir_function_signature *
-ir_function::exact_matching_signature(exec_list *actual_parameters)
-{
- foreach_iter(exec_list_iterator, iter, signatures) {
- ir_function_signature *const sig =
- (ir_function_signature *) iter.get();
-
- if (parameter_lists_match_exact(&sig->parameters, actual_parameters))
- return sig;
- }
- return NULL;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_function_can_inline.cpp
- *
- * Determines if we can inline a function call using ir_function_inlining.cpp.
- *
- * The primary restriction is that we can't return from the function
- * other than as the last instruction. We could potentially work
- * around this for some constructs by flattening control flow and
- * moving the return to the end, or by using breaks from a do {} while
- * (0) loop surrounding the function body.
- */
-
-#include "ir.h"
-
-class ir_function_can_inline_visitor : public ir_hierarchical_visitor {
-public:
- ir_function_can_inline_visitor()
- {
- this->num_returns = 0;
- }
-
- virtual ir_visitor_status visit_enter(ir_return *);
-
- int num_returns;
-};
-
-ir_visitor_status
-ir_function_can_inline_visitor::visit_enter(ir_return *ir)
-{
- (void) ir;
- this->num_returns++;
- return visit_continue;
-}
-
-bool
-can_inline(ir_call *call)
-{
- ir_function_can_inline_visitor v;
- const ir_function_signature *callee = call->get_callee();
-
- v.run((exec_list *) &callee->body);
-
- ir_instruction *last = (ir_instruction *)callee->body.get_tail();
- if (last && !last->as_return())
- v.num_returns++;
-
- return v.num_returns == 1;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_function_inlining.cpp
- *
- * Replaces calls to functions with the body of the function.
- */
-
-#include <inttypes.h>
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_function_inlining.h"
-#include "ir_expression_flattening.h"
-#include "glsl_types.h"
-#include "hash_table.h"
-
-class ir_function_inlining_visitor : public ir_hierarchical_visitor {
-public:
- ir_function_inlining_visitor()
- {
- progress = false;
- }
-
- virtual ~ir_function_inlining_visitor()
- {
- /* empty */
- }
-
- virtual ir_visitor_status visit_enter(ir_expression *);
- virtual ir_visitor_status visit_enter(ir_call *);
- virtual ir_visitor_status visit_enter(ir_assignment *);
- virtual ir_visitor_status visit_enter(ir_return *);
- virtual ir_visitor_status visit_enter(ir_texture *);
- virtual ir_visitor_status visit_enter(ir_swizzle *);
-
- bool progress;
-};
-
-
-unsigned int hash_func(const void *key)
-{
- return (unsigned int)(uintptr_t)key;
-}
-
-int hash_compare_func(const void *key1, const void *key2)
-{
- return key1 == key2 ? 0 : 1;
-}
-
-bool
-automatic_inlining_predicate(ir_instruction *ir)
-{
- ir_call *call = ir->as_call();
-
- if (call && can_inline(call))
- return true;
-
- return false;
-}
-
-bool
-do_function_inlining(exec_list *instructions)
-{
- ir_function_inlining_visitor v;
-
- do_expression_flattening(instructions, automatic_inlining_predicate);
-
- v.run(instructions);
-
- return v.progress;
-}
-
-static void
-replace_return_with_assignment(ir_instruction *ir, void *data)
-{
- void *ctx = talloc_parent(ir);
- ir_variable *retval = (ir_variable *)data;
- ir_return *ret = ir->as_return();
-
- if (ret) {
- if (ret->value) {
- ir_rvalue *lhs = new(ctx) ir_dereference_variable(retval);
- ret->insert_before(new(ctx) ir_assignment(lhs, ret->value, NULL));
- ret->remove();
- } else {
- /* un-valued return has to be the last return, or we shouldn't
- * have reached here. (see can_inline()).
- */
- assert(!ret->next->is_tail_sentinal());
- }
- }
-}
-
-ir_rvalue *
-ir_call::generate_inline(ir_instruction *next_ir)
-{
- void *ctx = talloc_parent(this);
- ir_variable **parameters;
- int num_parameters;
- int i;
- ir_variable *retval = NULL;
- struct hash_table *ht;
-
- ht = hash_table_ctor(0, hash_func, hash_compare_func);
-
- num_parameters = 0;
- foreach_iter(exec_list_iterator, iter_sig, this->callee->parameters)
- num_parameters++;
-
- parameters = new ir_variable *[num_parameters];
-
- /* Generate storage for the return value. */
- if (this->callee->return_type) {
- retval = new(ctx) ir_variable(this->callee->return_type, "__retval");
- next_ir->insert_before(retval);
- }
-
- /* Generate the declarations for the parameters to our inlined code,
- * and set up the mapping of real function body variables to ours.
- */
- i = 0;
- exec_list_iterator sig_param_iter = this->callee->parameters.iterator();
- exec_list_iterator param_iter = this->actual_parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get();
- ir_rvalue *param = (ir_rvalue *) param_iter.get();
-
- /* Generate a new variable for the parameter. */
- parameters[i] = (ir_variable *)sig_param->clone(ht);
- parameters[i]->mode = ir_var_auto;
- next_ir->insert_before(parameters[i]);
-
- /* Move the actual param into our param variable if it's an 'in' type. */
- if (sig_param->mode == ir_var_in ||
- sig_param->mode == ir_var_inout) {
- ir_assignment *assign;
-
- assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
- param, NULL);
- next_ir->insert_before(assign);
- }
-
- sig_param_iter.next();
- param_iter.next();
- }
-
- /* Generate the inlined body of the function. */
- foreach_iter(exec_list_iterator, iter, callee->body) {
- ir_instruction *ir = (ir_instruction *)iter.get();
- ir_instruction *new_ir = ir->clone(ht);
-
- next_ir->insert_before(new_ir);
- visit_tree(new_ir, replace_return_with_assignment, retval);
- }
-
- /* Copy back the value of any 'out' parameters from the function body
- * variables to our own.
- */
- i = 0;
- param_iter = this->actual_parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- ir_instruction *const param = (ir_instruction *) param_iter.get();
-
- /* Move our param variable into the actual param if it's an 'out' type. */
- if (parameters[i]->mode == ir_var_out ||
- parameters[i]->mode == ir_var_inout) {
- ir_assignment *assign;
-
- assign = new(ctx) ir_assignment(param->as_rvalue(),
- new(ctx) ir_dereference_variable(parameters[i]),
- NULL);
- next_ir->insert_before(assign);
- }
-
- param_iter.next();
- }
-
- delete [] parameters;
-
- hash_table_dtor(ht);
-
- if (retval)
- return new(ctx) ir_dereference_variable(retval);
- else
- return NULL;
-}
-
-
-ir_visitor_status
-ir_function_inlining_visitor::visit_enter(ir_expression *ir)
-{
- (void) ir;
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_function_inlining_visitor::visit_enter(ir_return *ir)
-{
- (void) ir;
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_function_inlining_visitor::visit_enter(ir_texture *ir)
-{
- (void) ir;
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_function_inlining_visitor::visit_enter(ir_swizzle *ir)
-{
- (void) ir;
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_function_inlining_visitor::visit_enter(ir_call *ir)
-{
- if (can_inline(ir)) {
- (void) ir->generate_inline(ir);
- ir->remove();
- this->progress = true;
- }
-
- return visit_continue;
-}
-
-
-ir_visitor_status
-ir_function_inlining_visitor::visit_enter(ir_assignment *ir)
-{
- ir_call *call = ir->rhs->as_call();
- if (!call || !can_inline(call))
- return visit_continue;
-
- /* generates the parameter setup, function body, and returns the return
- * value of the function
- */
- ir_rvalue *rhs = call->generate_inline(ir);
- assert(rhs);
-
- ir->rhs = rhs;
- this->progress = true;
-
- return visit_continue;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_function_inlining.h
- *
- * Replaces calls to functions with the body of the function.
- */
-
-bool can_inline(ir_call *call);
+++ /dev/null
-/*
- * 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 "ir.h"
-#include "ir_hierarchical_visitor.h"
-
-ir_hierarchical_visitor::ir_hierarchical_visitor()
-{
- this->callback = NULL;
- this->data = NULL;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit(ir_variable *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit(ir_constant *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit(ir_loop_jump *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_loop *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_loop *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_function_signature *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_function *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_function *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_expression *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_expression *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_texture *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_texture *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_swizzle *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_dereference_array *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_dereference_record *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_assignment *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_call *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_call *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_return *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_return *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_enter(ir_if *ir)
-{
- if (this->callback != NULL)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_hierarchical_visitor::visit_leave(ir_if *ir)
-{
- (void) ir;
- return visit_continue;
-}
-
-void
-ir_hierarchical_visitor::run(exec_list *instructions)
-{
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
-
- if (ir->accept(this) != visit_continue)
- break;
- }
-}
-
-
-void
-visit_tree(ir_instruction *ir,
- void (*callback)(class ir_instruction *ir, void *data),
- void *data)
-{
- ir_hierarchical_visitor v;
-
- v.callback = callback;
- v.data = data;
-
- ir->accept(&v);
-}
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#pragma once
-#ifndef IR_HIERARCHICAL_VISITOR_H
-#define IR_HIERARCHICAL_VISITOR_H
-
-/**
- * Enumeration values returned by visit methods to guide processing
- */
-enum ir_visitor_status {
- visit_continue, /**< Continue visiting as normal. */
- visit_continue_with_parent, /**< Don't visit siblings, continue w/parent. */
- visit_stop /**< Stop visiting immediately. */
-};
-
-
-/**
- * Base class of hierarchical visitors of IR instruction trees
- *
- * Hierarchical visitors differ from traditional visitors in a couple of
- * important ways. Rather than having a single \c visit method for each
- * subclass in the composite, there are three kinds of visit methods.
- * Leaf-node classes have a traditional \c visit method. Internal-node
- * classes have a \c visit_enter method, which is invoked just before
- * processing child nodes, and a \c visit_leave method which is invoked just
- * after processing child nodes.
- *
- * In addition, each visit method and the \c accept methods in the composite
- * have a return value which guides the navigation. Any of the visit methods
- * can choose to continue visiting the tree as normal (by returning \c
- * visit_continue), terminate visiting any further nodes immediately (by
- * returning \c visit_stop), or stop visiting sibling nodes (by returning \c
- * visit_continue_with_parent).
- *
- * These two changes combine to allow nagivation of children to be implemented
- * in the composite's \c accept method. The \c accept method for a leaf-node
- * class will simply call the \c visit method, as usual, and pass its return
- * value on. The \c accept method for internal-node classes will call the \c
- * visit_enter method, call the \c accpet method of each child node, and,
- * finally, call the \c visit_leave method. If any of these return a value
- * other that \c visit_continue, the correct action must be taken.
- *
- * The final benefit is that the hierarchical visitor base class need not be
- * abstract. Default implementations of every \c visit, \c visit_enter, and
- * \c visit_leave method can be provided. By default each of these methods
- * simply returns \c visit_continue. This allows a significant reduction in
- * derived class code.
- *
- * For more information about hierarchical visitors, see:
- *
- * http://c2.com/cgi/wiki?HierarchicalVisitorPattern
- * http://c2.com/cgi/wiki?HierarchicalVisitorDiscussion
- */
-
-class ir_hierarchical_visitor {
-public:
- ir_hierarchical_visitor();
-
- /**
- * \name Visit methods for leaf-node classes
- */
- /*@{*/
- virtual ir_visitor_status visit(class ir_variable *);
- virtual ir_visitor_status visit(class ir_constant *);
- virtual ir_visitor_status visit(class ir_loop_jump *);
-
- /**
- * ir_dereference_variable isn't technically a leaf, but it is treated as a
- * leaf here for a couple reasons. By not automatically visiting the one
- * child ir_variable node from the ir_dereference_variable, ir_variable
- * nodes can always be handled as variable declarations. Code that used
- * non-hierarchical visitors had to set an "in a dereference" flag to
- * determine how to handle an ir_variable. By forcing the visitor to
- * handle the ir_variable within the ir_dereference_variable visitor, this
- * kludge can be avoided.
- *
- * In addition, I can envision no use for having separate enter and leave
- * methods. Anything that could be done in the enter and leave methods
- * that couldn't just be done in the visit method.
- */
- virtual ir_visitor_status visit(class ir_dereference_variable *);
- /*@}*/
-
- /**
- * \name Visit methods for internal-node classes
- */
- /*@{*/
- virtual ir_visitor_status visit_enter(class ir_loop *);
- virtual ir_visitor_status visit_leave(class ir_loop *);
- virtual ir_visitor_status visit_enter(class ir_function_signature *);
- virtual ir_visitor_status visit_leave(class ir_function_signature *);
- virtual ir_visitor_status visit_enter(class ir_function *);
- virtual ir_visitor_status visit_leave(class ir_function *);
- virtual ir_visitor_status visit_enter(class ir_expression *);
- virtual ir_visitor_status visit_leave(class ir_expression *);
- virtual ir_visitor_status visit_enter(class ir_texture *);
- virtual ir_visitor_status visit_leave(class ir_texture *);
- virtual ir_visitor_status visit_enter(class ir_swizzle *);
- virtual ir_visitor_status visit_leave(class ir_swizzle *);
- virtual ir_visitor_status visit_enter(class ir_dereference_array *);
- virtual ir_visitor_status visit_leave(class ir_dereference_array *);
- virtual ir_visitor_status visit_enter(class ir_dereference_record *);
- virtual ir_visitor_status visit_leave(class ir_dereference_record *);
- virtual ir_visitor_status visit_enter(class ir_assignment *);
- virtual ir_visitor_status visit_leave(class ir_assignment *);
- virtual ir_visitor_status visit_enter(class ir_call *);
- virtual ir_visitor_status visit_leave(class ir_call *);
- virtual ir_visitor_status visit_enter(class ir_return *);
- virtual ir_visitor_status visit_leave(class ir_return *);
- virtual ir_visitor_status visit_enter(class ir_if *);
- virtual ir_visitor_status visit_leave(class ir_if *);
- /*@}*/
-
-
- /**
- * Utility function to process a linked list of instructions with a visitor
- */
- void run(struct exec_list *instructions);
-
- /**
- * Callback function that is invoked on entry to each node visited.
- *
- * \warning
- * Visitor classes derived from \c ir_hierarchical_visitor \b may \b not
- * invoke this function. This can be used, for example, to cause the
- * callback to be invoked on every node type execpt one.
- */
- void (*callback)(class ir_instruction *ir, void *data);
-
- /**
- * Extra data parameter passed to the per-node callback function
- */
- void *data;
-};
-
-void visit_tree(ir_instruction *ir,
- void (*callback)(class ir_instruction *ir, void *data),
- void *data);
-
-#endif /* IR_HIERARCHICAL_VISITOR_H */
+++ /dev/null
-/*
- * 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 "ir.h"
-
-/**
- * \file ir_hv_accept.cpp
- * Implementations of all hierarchical visitor accept methods for IR
- * instructions.
- */
-
-/**
- * Process a list of nodes using a hierarchical vistor
- *
- * \warning
- * This function will operate correctly if a node being processed is removed
- * from list. However, if nodes are added to the list after the node being
- * processed, some of the added noded may not be processed.
- */
-static ir_visitor_status
-visit_list_elements(ir_hierarchical_visitor *v, exec_list *l)
-{
- exec_node *next;
-
- for (exec_node *n = l->head; n->next != NULL; n = next) {
- next = n->next;
-
- ir_instruction *const ir = (ir_instruction *) n;
- ir_visitor_status s = ir->accept(v);
-
- if (s != visit_continue)
- return s;
- }
-
- return visit_continue;
-}
-
-
-ir_visitor_status
-ir_variable::accept(ir_hierarchical_visitor *v)
-{
- return v->visit(this);
-}
-
-
-ir_visitor_status
-ir_loop::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
-
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = visit_list_elements(v, &this->body_instructions);
- if (s == visit_stop)
- return s;
-
- if (s != visit_continue_with_parent) {
- if (this->from) {
- s = this->from->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
-
- if (this->to) {
- s = this->to->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
-
- if (this->increment) {
- s = this->increment->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
- }
-
- return v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_loop_jump::accept(ir_hierarchical_visitor *v)
-{
- return v->visit(this);
-}
-
-
-ir_visitor_status
-ir_function_signature::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = visit_list_elements(v, &this->body);
- return (s == visit_stop) ? s : v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_function::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = visit_list_elements(v, &this->signatures);
- return (s == visit_stop) ? s : v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_expression::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
-
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- for (unsigned i = 0; i < this->get_num_operands(); i++) {
- switch (this->operands[i]->accept(v)) {
- case visit_continue:
- break;
-
- case visit_continue_with_parent:
- // I wish for Java's labeled break-statement here.
- goto done;
-
- case visit_stop:
- return s;
- }
- }
-
-done:
- return v->visit_leave(this);
-}
-
-ir_visitor_status
-ir_texture::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->sampler->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->coordinate->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- if (this->projector) {
- s = this->projector->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
-
- if (this->shadow_comparitor) {
- s = this->shadow_comparitor->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
-
- switch (this->op) {
- case ir_tex:
- break;
- case ir_txb:
- s = this->lod_info.bias->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- break;
- case ir_txl:
- case ir_txf:
- s = this->lod_info.lod->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- break;
- case ir_txd:
- s = this->lod_info.grad.dPdx->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->lod_info.grad.dPdy->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- break;
- }
-
- return visit_continue_with_parent;
-}
-
-
-ir_visitor_status
-ir_swizzle::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->val->accept(v);
- return (s == visit_stop) ? s : v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_dereference_variable::accept(ir_hierarchical_visitor *v)
-{
- return v->visit(this);
-}
-
-
-ir_visitor_status
-ir_dereference_array::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->array_index->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->array->accept(v);
- return (s == visit_stop) ? s : v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_dereference_record::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->record->accept(v);
- return (s == visit_stop) ? s : v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_assignment::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->lhs->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->rhs->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- if (this->condition)
- s = this->condition->accept(v);
-
- return (s == visit_stop) ? s : v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_constant::accept(ir_hierarchical_visitor *v)
-{
- return v->visit(this);
-}
-
-
-ir_visitor_status
-ir_call::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = visit_list_elements(v, &this->actual_parameters);
- if (s == visit_stop)
- return s;
-
- return v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_return::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- ir_rvalue *val = this->get_value();
- if (val) {
- s = val->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
-
- return v->visit_leave(this);
-}
-
-
-ir_visitor_status
-ir_if::accept(ir_hierarchical_visitor *v)
-{
- ir_visitor_status s = v->visit_enter(this);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- s = this->condition->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
-
- if (s != visit_continue_with_parent) {
- s = visit_list_elements(v, &this->then_instructions);
- if (s == visit_stop)
- return s;
- }
-
- if (s != visit_continue_with_parent) {
- s = visit_list_elements(v, &this->else_instructions);
- if (s == visit_stop)
- return s;
- }
-
- return v->visit_leave(this);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_function_inlining.cpp
- *
- * Moves constant branches of if statements out to the surrounding
- * instruction stream.
- */
-
-#include "ir.h"
-
-class ir_if_simplification_visitor : public ir_hierarchical_visitor {
-public:
- ir_if_simplification_visitor()
- {
- this->made_progress = false;
- }
-
- ir_visitor_status visit_leave(ir_if *);
-
- bool made_progress;
-};
-
-bool
-do_if_simplification(exec_list *instructions)
-{
- ir_if_simplification_visitor v;
-
- v.run(instructions);
- return v.made_progress;
-}
-
-
-ir_visitor_status
-ir_if_simplification_visitor::visit_leave(ir_if *ir)
-{
- /* FINISHME: Ideally there would be a way to note that the condition results
- * FINISHME: in a constant before processing both of the other subtrees.
- * FINISHME: This can probably be done with some flags, but it would take
- * FINISHME: some work to get right.
- */
- ir_constant *condition_constant = ir->condition->constant_expression_value();
- if (condition_constant) {
- /* Move the contents of the one branch of the conditional
- * that matters out.
- */
- if (condition_constant->value.b[0]) {
- foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
- ir_instruction *then_ir = (ir_instruction *)then_iter.get();
- ir->insert_before(then_ir);
- }
- } else {
- foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
- ir_instruction *else_ir = (ir_instruction *)else_iter.get();
- ir->insert_before(else_ir);
- }
- }
- ir->remove();
- this->made_progress = true;
- }
-
- return visit_continue;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-
-/**
- * \file ir_dead_code.h
- *
- * Prototypes for optimization passes to be called by the compiler and drivers.
- */
-
-bool do_constant_folding(exec_list *instructions);
-bool do_constant_variable(exec_list *instructions);
-bool do_constant_variable_unlinked(exec_list *instructions);
-bool do_copy_propagation(exec_list *instructions);
-bool do_dead_code(exec_list *instructions);
-bool do_dead_code_local(exec_list *instructions);
-bool do_dead_code_unlinked(exec_list *instructions);
-bool do_function_inlining(exec_list *instructions);
-bool do_if_simplification(exec_list *instructions);
-bool do_swizzle_swizzle(exec_list *instructions);
-bool do_vec_index_to_swizzle(exec_list *instructions);
+++ /dev/null
-/*
- * 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 "ir_print_visitor.h"
-#include "glsl_types.h"
-#include "glsl_parser_extras.h"
-
-static void print_type(const glsl_type *t);
-
-void
-ir_instruction::print(void) const
-{
- ir_instruction *deconsted = const_cast<ir_instruction *>(this);
-
- ir_print_visitor v;
- deconsted->accept(&v);
-}
-
-void
-_mesa_print_ir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- for (unsigned i = 0; i < state->num_user_structures; i++) {
- const glsl_type *const s = state->user_structures[i];
-
- printf("(structure (%s) (%s@%p) (%u) (\n",
- s->name, s->name, s, s->length);
-
- for (unsigned j = 0; j < s->length; j++) {
- printf("\t((");
- print_type(s->fields.structure[j].type);
- printf(")(%s))\n", s->fields.structure[j].name);
- }
-
- printf(")\n");
- }
-
- printf("(\n");
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ((ir_instruction *)iter.get())->print();
- printf("\n");
- }
- printf("\n)");
-}
-
-static void
-print_type(const glsl_type *t)
-{
- if (t->base_type == GLSL_TYPE_ARRAY) {
- printf("(array ");
- print_type(t->fields.array);
- printf(" %u)", t->length);
- } else if ((t->base_type == GLSL_TYPE_STRUCT)
- && (strncmp("gl_", t->name, 3) != 0)) {
- printf("%s@%p", t->name, t);
- } else {
- printf("%s", t->name);
- }
-}
-
-
-void ir_print_visitor::visit(ir_variable *ir)
-{
- printf("(declare ");
-
- const char *const cent = (ir->centroid) ? "centroid " : "";
- const char *const inv = (ir->invariant) ? "invariant " : "";
- const char *const mode[] = { "", "uniform ", "in ", "out ", "inout " };
- const char *const interp[] = { "", "flat", "noperspective" };
-
- printf("(%s%s%s%s) ",
- cent, inv, mode[ir->mode], interp[ir->interpolation]);
-
- print_type(ir->type);
- printf(" %s@%p)", ir->name, ir);
-}
-
-
-void ir_print_visitor::visit(ir_function_signature *ir)
-{
- printf("(signature ");
- print_type(ir->return_type);
- printf("\n (parameters\n");
- foreach_iter(exec_list_iterator, iter, ir->parameters) {
- ir_variable *const inst = (ir_variable *) iter.get();
-
- inst->accept(this);
- printf("\n");
- }
- printf(" )\n(");
-
- foreach_iter(exec_list_iterator, iter, ir->body) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
-
- inst->accept(this);
- printf("\n");
- }
- printf("))\n");
-}
-
-
-void ir_print_visitor::visit(ir_function *ir)
-{
- printf("(function %s\n", ir->name);
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_function_signature *const sig = (ir_function_signature *) iter.get();
-
- sig->accept(this);
- printf("\n");
- }
-
- printf(")\n");
-}
-
-
-void ir_print_visitor::visit(ir_expression *ir)
-{
- printf("(expression ");
-
- print_type(ir->type);
-
- printf(" %s ", ir->operator_string());
-
- if (ir->operands[0])
- ir->operands[0]->accept(this);
-
- if (ir->operands[1])
- ir->operands[1]->accept(this);
- printf(") ");
-}
-
-
-void ir_print_visitor::visit(ir_texture *ir)
-{
- printf("(%s ", ir->opcode_string());
-
- ir->sampler->accept(this);
- printf(" ");
-
- ir->coordinate->accept(this);
-
- printf(" (%d %d %d) ", ir->offsets[0], ir->offsets[1], ir->offsets[2]);
-
- if (ir->op != ir_txf) {
- if (ir->projector)
- ir->projector->accept(this);
- else
- printf("1");
-
- if (ir->shadow_comparitor) {
- printf(" ");
- ir->shadow_comparitor->accept(this);
- } else {
- printf(" ()");
- }
- }
-
- printf(" ");
- switch (ir->op)
- {
- case ir_tex:
- break;
- case ir_txb:
- ir->lod_info.bias->accept(this);
- break;
- case ir_txl:
- case ir_txf:
- ir->lod_info.lod->accept(this);
- break;
- case ir_txd:
- printf("(");
- ir->lod_info.grad.dPdx->accept(this);
- printf(" ");
- ir->lod_info.grad.dPdy->accept(this);
- printf(")");
- break;
- };
- printf(")");
-}
-
-
-void ir_print_visitor::visit(ir_swizzle *ir)
-{
- const unsigned swiz[4] = {
- ir->mask.x,
- ir->mask.y,
- ir->mask.z,
- ir->mask.w,
- };
-
- printf("(swiz ");
- for (unsigned i = 0; i < ir->mask.num_components; i++) {
- printf("%c", "xyzw"[swiz[i]]);
- }
- printf(" ");
- ir->val->accept(this);
- printf(")");
-}
-
-
-void ir_print_visitor::visit(ir_dereference_variable *ir)
-{
- ir_variable *var = ir->variable_referenced();
- printf("(var_ref %s@%p) ", var->name, var);
-}
-
-
-void ir_print_visitor::visit(ir_dereference_array *ir)
-{
- printf("(array_ref ");
- ir->array->accept(this);
- ir->array_index->accept(this);
- printf(") ");
-}
-
-
-void ir_print_visitor::visit(ir_dereference_record *ir)
-{
- printf("(record_ref ");
- ir->record->accept(this);
- printf(" %s) ", ir->field);
-}
-
-
-void ir_print_visitor::visit(ir_assignment *ir)
-{
- printf("(assign ");
-
- if (ir->condition)
- ir->condition->accept(this);
- else
- printf("(constant bool (1))");
-
- printf(" ");
-
- ir->lhs->accept(this);
-
- printf(" ");
-
- ir->rhs->accept(this);
- printf(") ");
-}
-
-
-void ir_print_visitor::visit(ir_constant *ir)
-{
- const glsl_type *const base_type = ir->type->get_base_type();
-
- printf("(constant ");
- print_type(ir->type);
- printf(" (");
-
- for (unsigned i = 0; i < ir->type->components(); i++) {
- if (i != 0)
- printf(", ");
-
- switch (base_type->base_type) {
- case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break;
- case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break;
- case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
- case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break;
- default: assert(0);
- }
- }
- printf(")) ");
-}
-
-
-void
-ir_print_visitor::visit(ir_call *ir)
-{
- printf("(call %s (", ir->callee_name());
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
-
- inst->accept(this);
- }
- printf("))\n");
-}
-
-
-void
-ir_print_visitor::visit(ir_return *ir)
-{
- printf("(return");
-
- ir_rvalue *const value = ir->get_value();
- if (value) {
- printf(" ");
- value->accept(this);
- }
-
- printf(")");
-}
-
-
-void
-ir_print_visitor::visit(ir_if *ir)
-{
- printf("(if ");
- ir->condition->accept(this);
-
- printf("(\n");
- foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
-
- inst->accept(this);
- printf("\n");
- }
- printf(")\n");
-
- printf("(\n");
- foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
-
- inst->accept(this);
- printf("\n");
- }
- printf("))\n");
-}
-
-
-void
-ir_print_visitor::visit(ir_loop *ir)
-{
- printf("(loop (");
- if (ir->counter != NULL)
- ir->counter->accept(this);
- printf(") (");
- if (ir->from != NULL)
- ir->from->accept(this);
- printf(") (");
- if (ir->to != NULL)
- ir->to->accept(this);
- printf(") (");
- if (ir->increment != NULL)
- ir->increment->accept(this);
- printf(") (\n");
- foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
-
- inst->accept(this);
- printf("\n");
- }
- printf("))\n");
-}
-
-
-void
-ir_print_visitor::visit(ir_loop_jump *ir)
-{
- printf("%s", ir->is_break() ? "break" : "continue");
-}
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#pragma once
-#ifndef IR_PRINT_VISITOR_H
-#define IR_PRINT_VISITOR_H
-
-#include "ir.h"
-#include "ir_visitor.h"
-
-extern void _mesa_print_ir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state);
-
-/**
- * Abstract base class of visitors of IR instruction trees
- */
-class ir_print_visitor : public ir_visitor {
-public:
- ir_print_visitor()
- : deref_depth(0)
- {
- /* empty */
- }
-
- virtual ~ir_print_visitor()
- {
- /* empty */
- }
-
- /**
- * \name Visit methods
- *
- * As typical for the visitor pattern, there must be one \c visit method for
- * each concrete subclass of \c ir_instruction. Virtual base classes within
- * the hierarchy should not have \c visit methods.
- */
- /*@{*/
- virtual void visit(ir_variable *);
- virtual void visit(ir_function_signature *);
- virtual void visit(ir_function *);
- virtual void visit(ir_expression *);
- virtual void visit(ir_texture *);
- virtual void visit(ir_swizzle *);
- virtual void visit(ir_dereference_variable *);
- virtual void visit(ir_dereference_array *);
- virtual void visit(ir_dereference_record *);
- virtual void visit(ir_assignment *);
- virtual void visit(ir_constant *);
- virtual void visit(ir_call *);
- virtual void visit(ir_return *);
- virtual void visit(ir_if *);
- virtual void visit(ir_loop *);
- virtual void visit(ir_loop_jump *);
- /*@}*/
-
-private:
- int deref_depth;
-};
-
-#endif /* IR_PRINT_VISITOR_H */
+++ /dev/null
-/*
- * 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 <cstdarg>
-
-extern "C" {
-#include <talloc.h>
-}
-
-#include "ir_reader.h"
-#include "glsl_parser_extras.h"
-#include "glsl_types.h"
-#include "s_expression.h"
-
-static void ir_read_error(_mesa_glsl_parse_state *, s_expression *,
- const char *fmt, ...);
-static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
-
-static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
- s_expression *);
-static ir_function *read_function(_mesa_glsl_parse_state *, s_list *,
- bool skip_body);
-static void read_function_sig(_mesa_glsl_parse_state *, ir_function *,
- s_list *, bool skip_body);
-
-static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
- s_expression *, ir_loop *);
-static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
- s_expression *, ir_loop *);
-static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_list *);
-static ir_if *read_if(_mesa_glsl_parse_state *, s_list *, ir_loop *);
-static ir_loop *read_loop(_mesa_glsl_parse_state *st, s_list *list);
-static ir_return *read_return(_mesa_glsl_parse_state *, s_list *);
-
-static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
-static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *);
-static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *);
-static ir_call *read_call(_mesa_glsl_parse_state *, s_list *);
-static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *);
-static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *);
-static ir_texture *read_texture(_mesa_glsl_parse_state *, s_list *);
-
-static ir_dereference *read_dereference(_mesa_glsl_parse_state *,
- s_expression *);
-static ir_dereference *read_var_ref(_mesa_glsl_parse_state *, s_list *);
-static ir_dereference *read_array_ref(_mesa_glsl_parse_state *, s_list *);
-static ir_dereference *read_record_ref(_mesa_glsl_parse_state *, s_list *);
-
-void
-_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
- const char *src)
-{
- void *ctx = talloc_parent(state);
- s_expression *expr = s_expression::read_expression(ctx, src);
- if (expr == NULL) {
- ir_read_error(state, NULL, "couldn't parse S-Expression.");
- return;
- }
-
- scan_for_prototypes(state, instructions, expr);
- if (state->error)
- return;
-
- read_instructions(state, instructions, expr, NULL);
-}
-
-static void
-ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,
- const char *fmt, ...)
-{
- va_list ap;
-
- state->error = true;
-
- state->info_log = talloc_strdup_append(state->info_log, "error: ");
-
- 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");
-
- if (expr != NULL) {
- state->info_log = talloc_strdup_append(state->info_log,
- "...in this context:\n ");
- expr->print();
- state->info_log = talloc_strdup_append(state->info_log, "\n\n");
- }
-}
-
-static const glsl_type *
-read_type(_mesa_glsl_parse_state *st, s_expression *expr)
-{
- s_list *list = SX_AS_LIST(expr);
- if (list != NULL) {
- s_symbol *type_sym = SX_AS_SYMBOL(list->subexpressions.get_head());
- if (type_sym == NULL) {
- ir_read_error(st, expr, "expected type (array ...) or (struct ...)");
- return NULL;
- }
- if (strcmp(type_sym->value(), "array") == 0) {
- if (list->length() != 3) {
- ir_read_error(st, expr, "expected type (array <type> <int>)");
- return NULL;
- }
-
- // Read base type
- s_expression *base_expr = (s_expression*) type_sym->next;
- const glsl_type *base_type = read_type(st, base_expr);
- if (base_type == NULL) {
- ir_read_error(st, NULL, "when reading base type of array");
- return NULL;
- }
-
- // Read array size
- s_int *size = SX_AS_INT(base_expr->next);
- if (size == NULL) {
- ir_read_error(st, expr, "found non-integer array size");
- return NULL;
- }
-
- return glsl_type::get_array_instance(st, base_type, size->value());
- } else if (strcmp(type_sym->value(), "struct") == 0) {
- assert(false); // FINISHME
- } else {
- ir_read_error(st, expr, "expected (array ...) or (struct ...); "
- "found (%s ...)", type_sym->value());
- return NULL;
- }
- }
-
- s_symbol *type_sym = SX_AS_SYMBOL(expr);
- if (type_sym == NULL) {
- ir_read_error(st, expr, "expected <type> (symbol or list)");
- return NULL;
- }
-
- const glsl_type *type = st->symbols->get_type(type_sym->value());
- if (type == NULL)
- ir_read_error(st, expr, "invalid type: %s", type_sym->value());
-
- return type;
-}
-
-
-static void
-scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
- s_expression *expr)
-{
- s_list *list = SX_AS_LIST(expr);
- if (list == NULL) {
- ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
- return;
- }
-
- foreach_iter(exec_list_iterator, it, list->subexpressions) {
- s_list *sub = SX_AS_LIST(it.get());
- if (sub == NULL)
- continue; // not a (function ...); ignore it.
-
- s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
- if (tag == NULL || strcmp(tag->value(), "function") != 0)
- continue; // not a (function ...); ignore it.
-
- ir_function *f = read_function(st, sub, true);
- if (f == NULL)
- return;
- instructions->push_tail(f);
- }
-}
-
-static ir_function *
-read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
-{
- void *ctx = talloc_parent(st);
- if (list->length() < 3) {
- ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
- return NULL;
- }
-
- s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
- if (name == NULL) {
- ir_read_error(st, list, "Expected (function <name> ...)");
- return NULL;
- }
-
- ir_function *f = st->symbols->get_function(name->value());
- if (f == NULL) {
- f = new(ctx) ir_function(name->value());
- bool added = st->symbols->add_function(name->value(), f);
- assert(added);
- }
-
- exec_list_iterator it = list->subexpressions.iterator();
- it.next(); // skip "function" tag
- it.next(); // skip function name
- for (/* nothing */; it.has_next(); it.next()) {
- s_list *siglist = SX_AS_LIST(it.get());
- if (siglist == NULL) {
- ir_read_error(st, list, "Expected (function (signature ...) ...)");
- return NULL;
- }
-
- s_symbol *tag = SX_AS_SYMBOL(siglist->subexpressions.get_head());
- if (tag == NULL || strcmp(tag->value(), "signature") != 0) {
- ir_read_error(st, siglist, "Expected (signature ...)");
- return NULL;
- }
-
- read_function_sig(st, f, siglist, skip_body);
- }
- return f;
-}
-
-static void
-read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
- bool skip_body)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 4) {
- ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
- "(<instruction> ...))");
- return;
- }
-
- s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
- const glsl_type *return_type = read_type(st, type_expr);
- if (return_type == NULL)
- return;
-
- s_list *paramlist = SX_AS_LIST(type_expr->next);
- s_list *body_list = SX_AS_LIST(paramlist->next);
- if (paramlist == NULL || body_list == NULL) {
- ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
- "(<instruction> ...))");
- return;
- }
- s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
- if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
- ir_read_error(st, paramlist, "Expected (parameters ...)");
- return;
- }
-
- // Read the parameters list into a temporary place.
- exec_list hir_parameters;
- st->symbols->push_scope();
-
- exec_list_iterator it = paramlist->subexpressions.iterator();
- for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
- s_list *decl = SX_AS_LIST(it.get());
- ir_variable *var = read_declaration(st, decl);
- if (var == NULL)
- return;
-
- hir_parameters.push_tail(var);
- }
-
- ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
- if (sig != NULL) {
- const char *badvar = sig->qualifiers_match(&hir_parameters);
- if (badvar != NULL) {
- ir_read_error(st, list, "function `%s' parameter `%s' qualifiers "
- "don't match prototype", f->name, badvar);
- return;
- }
-
- if (sig->return_type != return_type) {
- ir_read_error(st, list, "function `%s' return type doesn't "
- "match prototype", f->name);
- return;
- }
- } else {
- sig = new(ctx) ir_function_signature(return_type);
- f->add_signature(sig);
- }
-
- sig->replace_parameters(&hir_parameters);
-
- if (!skip_body) {
- if (sig->is_defined) {
- ir_read_error(st, list, "function %s redefined", f->name);
- return;
- }
- read_instructions(st, &sig->body, body_list, NULL);
- sig->is_defined = true;
- }
-
- st->symbols->pop_scope();
-}
-
-static void
-read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
- s_expression *expr, ir_loop *loop_ctx)
-{
- // Read in a list of instructions
- s_list *list = SX_AS_LIST(expr);
- if (list == NULL) {
- ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
- return;
- }
-
- foreach_iter(exec_list_iterator, it, list->subexpressions) {
- s_expression *sub = (s_expression*) it.get();
- ir_instruction *ir = read_instruction(st, sub, loop_ctx);
- if (ir == NULL) {
- ir_read_error(st, sub, "Invalid instruction.\n");
- return;
- }
- instructions->push_tail(ir);
- }
-}
-
-
-static ir_instruction *
-read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
- ir_loop *loop_ctx)
-{
- void *ctx = talloc_parent(st);
- s_symbol *symbol = SX_AS_SYMBOL(expr);
- if (symbol != NULL) {
- if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
- return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
- if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
- return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
- }
-
- s_list *list = SX_AS_LIST(expr);
- if (list == NULL || list->subexpressions.is_empty())
- return NULL;
-
- s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
- if (tag == NULL) {
- ir_read_error(st, expr, "expected instruction tag");
- return NULL;
- }
-
- ir_instruction *inst = NULL;
- if (strcmp(tag->value(), "declare") == 0) {
- inst = read_declaration(st, list);
- } else if (strcmp(tag->value(), "if") == 0) {
- inst = read_if(st, list, loop_ctx);
- } else if (strcmp(tag->value(), "loop") == 0) {
- inst = read_loop(st, list);
- } else if (strcmp(tag->value(), "return") == 0) {
- inst = read_return(st, list);
- } else if (strcmp(tag->value(), "function") == 0) {
- inst = read_function(st, list, false);
- } else {
- inst = read_rvalue(st, list);
- if (inst == NULL)
- ir_read_error(st, NULL, "when reading instruction");
- }
- return inst;
-}
-
-
-static ir_variable *
-read_declaration(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 4) {
- ir_read_error(st, list, "expected (declare (<qualifiers>) <type> "
- "<name>)");
- return NULL;
- }
-
- s_list *quals = SX_AS_LIST(list->subexpressions.head->next);
- if (quals == NULL) {
- ir_read_error(st, list, "expected a list of variable qualifiers");
- return NULL;
- }
-
- s_expression *type_expr = (s_expression*) quals->next;
- const glsl_type *type = read_type(st, type_expr);
- if (type == NULL)
- return NULL;
-
- s_symbol *var_name = SX_AS_SYMBOL(type_expr->next);
- if (var_name == NULL) {
- ir_read_error(st, list, "expected variable name, found non-symbol");
- return NULL;
- }
-
- ir_variable *var = new(ctx) ir_variable(type, var_name->value());
-
- foreach_iter(exec_list_iterator, it, quals->subexpressions) {
- s_symbol *qualifier = SX_AS_SYMBOL(it.get());
- if (qualifier == NULL) {
- ir_read_error(st, list, "qualifier list must contain only symbols");
- delete var;
- return NULL;
- }
-
- // FINISHME: Check for duplicate/conflicting qualifiers.
- if (strcmp(qualifier->value(), "centroid") == 0) {
- var->centroid = 1;
- } else if (strcmp(qualifier->value(), "invariant") == 0) {
- var->invariant = 1;
- } else if (strcmp(qualifier->value(), "uniform") == 0) {
- var->mode = ir_var_uniform;
- } else if (strcmp(qualifier->value(), "auto") == 0) {
- var->mode = ir_var_auto;
- } else if (strcmp(qualifier->value(), "in") == 0) {
- var->mode = ir_var_in;
- } else if (strcmp(qualifier->value(), "out") == 0) {
- var->mode = ir_var_out;
- } else if (strcmp(qualifier->value(), "inout") == 0) {
- var->mode = ir_var_inout;
- } else if (strcmp(qualifier->value(), "smooth") == 0) {
- var->interpolation = ir_var_smooth;
- } else if (strcmp(qualifier->value(), "flat") == 0) {
- var->interpolation = ir_var_flat;
- } else if (strcmp(qualifier->value(), "noperspective") == 0) {
- var->interpolation = ir_var_noperspective;
- } else {
- ir_read_error(st, list, "unknown qualifier: %s", qualifier->value());
- delete var;
- return NULL;
- }
- }
-
- // Add the variable to the symbol table
- st->symbols->add_variable(var_name->value(), var);
-
- return var;
-}
-
-
-static ir_if *
-read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 4) {
- ir_read_error(st, list, "expected (if <condition> (<then> ...) "
- "(<else> ...))");
- return NULL;
- }
-
- s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
- ir_rvalue *condition = read_rvalue(st, cond_expr);
- if (condition == NULL) {
- ir_read_error(st, NULL, "when reading condition of (if ...)");
- return NULL;
- }
-
- s_expression *then_expr = (s_expression*) cond_expr->next;
- s_expression *else_expr = (s_expression*) then_expr->next;
-
- ir_if *iff = new(ctx) ir_if(condition);
-
- read_instructions(st, &iff->then_instructions, then_expr, loop_ctx);
- read_instructions(st, &iff->else_instructions, else_expr, loop_ctx);
- if (st->error) {
- delete iff;
- iff = NULL;
- }
- return iff;
-}
-
-
-static ir_loop *
-read_loop(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 6) {
- ir_read_error(st, list, "expected (loop <counter> <from> <to> "
- "<increment> <body>)");
- return NULL;
- }
-
- s_expression *count_expr = (s_expression*) list->subexpressions.head->next;
- s_expression *from_expr = (s_expression*) count_expr->next;
- s_expression *to_expr = (s_expression*) from_expr->next;
- s_expression *inc_expr = (s_expression*) to_expr->next;
- s_expression *body_expr = (s_expression*) inc_expr->next;
-
- // FINISHME: actually read the count/from/to fields.
-
- ir_loop *loop = new(ctx) ir_loop;
- read_instructions(st, &loop->body_instructions, body_expr, loop);
- if (st->error) {
- delete loop;
- loop = NULL;
- }
- return loop;
-}
-
-
-static ir_return *
-read_return(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 2) {
- ir_read_error(st, list, "expected (return <rvalue>)");
- return NULL;
- }
-
- s_expression *expr = (s_expression*) list->subexpressions.head->next;
-
- ir_rvalue *retval = read_rvalue(st, expr);
- if (retval == NULL) {
- ir_read_error(st, NULL, "when reading return value");
- return NULL;
- }
-
- return new(ctx) ir_return(retval);
-}
-
-
-static ir_rvalue *
-read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
-{
- s_list *list = SX_AS_LIST(expr);
- if (list == NULL || list->subexpressions.is_empty())
- return NULL;
-
- s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
- if (tag == NULL) {
- ir_read_error(st, expr, "expected rvalue tag");
- return NULL;
- }
-
- ir_rvalue *rvalue = read_dereference(st, list);
- if (rvalue != NULL || st->error)
- return rvalue;
- else if (strcmp(tag->value(), "swiz") == 0) {
- rvalue = read_swizzle(st, list);
- } else if (strcmp(tag->value(), "assign") == 0) {
- rvalue = read_assignment(st, list);
- } else if (strcmp(tag->value(), "expression") == 0) {
- rvalue = read_expression(st, list);
- } else if (strcmp(tag->value(), "call") == 0) {
- rvalue = read_call(st, list);
- } else if (strcmp(tag->value(), "constant") == 0) {
- rvalue = read_constant(st, list);
- } else {
- rvalue = read_texture(st, list);
- if (rvalue == NULL && !st->error)
- ir_read_error(st, expr, "unrecognized rvalue tag: %s", tag->value());
- }
-
- return rvalue;
-}
-
-static ir_assignment *
-read_assignment(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 4) {
- ir_read_error(st, list, "expected (assign <condition> <lhs> <rhs>)");
- return NULL;
- }
-
- s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
- s_expression *lhs_expr = (s_expression*) cond_expr->next;
- s_expression *rhs_expr = (s_expression*) lhs_expr->next;
-
- // FINISHME: Deal with "true" condition
- ir_rvalue *condition = read_rvalue(st, cond_expr);
- if (condition == NULL) {
- ir_read_error(st, NULL, "when reading condition of assignment");
- return NULL;
- }
-
- ir_rvalue *lhs = read_rvalue(st, lhs_expr);
- if (lhs == NULL) {
- ir_read_error(st, NULL, "when reading left-hand side of assignment");
- return NULL;
- }
-
- ir_rvalue *rhs = read_rvalue(st, rhs_expr);
- if (rhs == NULL) {
- ir_read_error(st, NULL, "when reading right-hand side of assignment");
- return NULL;
- }
-
- return new(ctx) ir_assignment(lhs, rhs, condition);
-}
-
-static ir_call *
-read_call(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 3) {
- ir_read_error(st, list, "expected (call <name> (<param> ...))");
- return NULL;
- }
-
- s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
- s_list *params = SX_AS_LIST(name->next);
- if (name == NULL || params == NULL) {
- ir_read_error(st, list, "expected (call <name> (<param> ...))");
- return NULL;
- }
-
- exec_list parameters;
-
- foreach_iter(exec_list_iterator, it, params->subexpressions) {
- s_expression *expr = (s_expression*) it.get();
- ir_rvalue *param = read_rvalue(st, expr);
- if (param == NULL) {
- ir_read_error(st, list, "when reading parameter to function call");
- return NULL;
- }
- parameters.push_tail(param);
- }
-
- ir_function *f = st->symbols->get_function(name->value());
- if (f == NULL) {
- ir_read_error(st, list, "found call to undefined function %s",
- name->value());
- return NULL;
- }
-
- const ir_function_signature *callee = f->matching_signature(¶meters);
- if (callee == NULL) {
- ir_read_error(st, list, "couldn't find matching signature for function "
- "%s", name->value());
- return NULL;
- }
-
- return new(ctx) ir_call(callee, ¶meters);
-}
-
-static ir_expression *
-read_expression(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- const unsigned list_length = list->length();
- if (list_length < 4) {
- ir_read_error(st, list, "expected (expression <type> <operator> "
- "<operand> [<operand>])");
- return NULL;
- }
-
- s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
- const glsl_type *type = read_type(st, type_expr);
- if (type == NULL)
- return NULL;
-
- /* Read the operator */
- s_symbol *op_sym = SX_AS_SYMBOL(type_expr->next);
- if (op_sym == NULL) {
- ir_read_error(st, list, "expected operator, found non-symbol");
- return NULL;
- }
-
- ir_expression_operation op = ir_expression::get_operator(op_sym->value());
- if (op == (ir_expression_operation) -1) {
- ir_read_error(st, list, "invalid operator: %s", op_sym->value());
- return NULL;
- }
-
- /* Now that we know the operator, check for the right number of operands */
- if (ir_expression::get_num_operands(op) == 2) {
- if (list_length != 5) {
- ir_read_error(st, list, "expected (expression <type> %s <operand> "
- " <operand>)", op_sym->value());
- return NULL;
- }
- } else {
- if (list_length != 4) {
- ir_read_error(st, list, "expected (expression <type> %s <operand>)",
- op_sym->value());
- return NULL;
- }
- }
-
- s_expression *exp1 = (s_expression*) (op_sym->next);
- ir_rvalue *arg1 = read_rvalue(st, exp1);
- if (arg1 == NULL) {
- ir_read_error(st, NULL, "when reading first operand of %s",
- op_sym->value());
- return NULL;
- }
-
- ir_rvalue *arg2 = NULL;
- if (ir_expression::get_num_operands(op) == 2) {
- s_expression *exp2 = (s_expression*) (exp1->next);
- arg2 = read_rvalue(st, exp2);
- if (arg2 == NULL) {
- ir_read_error(st, NULL, "when reading second operand of %s",
- op_sym->value());
- return NULL;
- }
- }
-
- return new(ctx) ir_expression(op, type, arg1, arg2);
-}
-
-static ir_swizzle *
-read_swizzle(_mesa_glsl_parse_state *st, s_list *list)
-{
- if (list->length() != 3) {
- ir_read_error(st, list, "expected (swiz <swizzle> <rvalue>)");
- return NULL;
- }
-
- s_symbol *swiz = SX_AS_SYMBOL(list->subexpressions.head->next);
- if (swiz == NULL) {
- ir_read_error(st, list, "expected a valid swizzle; found non-symbol");
- return NULL;
- }
-
- if (strlen(swiz->value()) > 4) {
- ir_read_error(st, list, "expected a valid swizzle; found %s",
- swiz->value());
- return NULL;
- }
-
- s_expression *sub = (s_expression*) swiz->next;
- if (sub == NULL) {
- ir_read_error(st, list, "expected rvalue: (swizzle %s <rvalue>)",
- swiz->value());
- return NULL;
- }
-
- ir_rvalue *rvalue = read_rvalue(st, sub);
- if (rvalue == NULL)
- return NULL;
-
- ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
- rvalue->type->vector_elements);
- if (ir == NULL)
- ir_read_error(st, list, "invalid swizzle");
-
- return ir;
-}
-
-static ir_constant *
-read_constant(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 3) {
- ir_read_error(st, list, "expected (constant <type> (<num> ... <num>))");
- return NULL;
- }
-
- s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
- const glsl_type *type = read_type(st, type_expr);
- if (type == NULL)
- return NULL;
-
- s_list *values = SX_AS_LIST(type_expr->next);
- if (values == NULL) {
- ir_read_error(st, list, "expected (constant <type> (<num> ... <num>))");
- return NULL;
- }
-
- const glsl_type *const base_type = type->get_base_type();
-
- ir_constant_data data;
-
- // Read in list of values (at most 16).
- int k = 0;
- foreach_iter(exec_list_iterator, it, values->subexpressions) {
- if (k >= 16) {
- ir_read_error(st, values, "expected at most 16 numbers");
- return NULL;
- }
-
- s_expression *expr = (s_expression*) it.get();
-
- if (base_type->base_type == GLSL_TYPE_FLOAT) {
- s_number *value = SX_AS_NUMBER(expr);
- if (value == NULL) {
- ir_read_error(st, values, "expected numbers");
- return NULL;
- }
- data.f[k] = value->fvalue();
- } else {
- s_int *value = SX_AS_INT(expr);
- if (value == NULL) {
- ir_read_error(st, values, "expected integers");
- return NULL;
- }
-
- switch (base_type->base_type) {
- case GLSL_TYPE_UINT: {
- data.u[k] = value->value();
- break;
- }
- case GLSL_TYPE_INT: {
- data.i[k] = value->value();
- break;
- }
- case GLSL_TYPE_BOOL: {
- data.b[k] = value->value();
- break;
- }
- default:
- ir_read_error(st, values, "unsupported constant type");
- return NULL;
- }
- }
- ++k;
- }
-
- return new(ctx) ir_constant(type, &data);
-}
-
-static ir_dereference *
-read_dereference(_mesa_glsl_parse_state *st, s_expression *expr)
-{
- s_list *list = SX_AS_LIST(expr);
- if (list == NULL || list->subexpressions.is_empty())
- return NULL;
-
- s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
- assert(tag != NULL);
-
- if (strcmp(tag->value(), "var_ref") == 0)
- return read_var_ref(st, list);
- if (strcmp(tag->value(), "array_ref") == 0)
- return read_array_ref(st, list);
- if (strcmp(tag->value(), "record_ref") == 0)
- return read_record_ref(st, list);
- return NULL;
-}
-
-static ir_dereference *
-read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 2) {
- ir_read_error(st, list, "expected (var_ref <variable name>)");
- return NULL;
- }
- s_symbol *var_name = SX_AS_SYMBOL(list->subexpressions.head->next);
- if (var_name == NULL) {
- ir_read_error(st, list, "expected (var_ref <variable name>)");
- return NULL;
- }
-
- ir_variable *var = st->symbols->get_variable(var_name->value());
- if (var == NULL) {
- ir_read_error(st, list, "undeclared variable: %s", var_name->value());
- return NULL;
- }
-
- return new(ctx) ir_dereference_variable(var);
-}
-
-static ir_dereference *
-read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 3) {
- ir_read_error(st, list, "expected (array_ref <rvalue> <index>)");
- return NULL;
- }
-
- s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
- ir_rvalue *subject = read_rvalue(st, subj_expr);
- if (subject == NULL) {
- ir_read_error(st, NULL, "when reading the subject of an array_ref");
- return NULL;
- }
-
- s_expression *idx_expr = (s_expression*) subj_expr->next;
- ir_rvalue *idx = read_rvalue(st, idx_expr);
- return new(ctx) ir_dereference_array(subject, idx);
-}
-
-static ir_dereference *
-read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- if (list->length() != 3) {
- ir_read_error(st, list, "expected (record_ref <rvalue> <field>)");
- return NULL;
- }
-
- s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
- ir_rvalue *subject = read_rvalue(st, subj_expr);
- if (subject == NULL) {
- ir_read_error(st, NULL, "when reading the subject of a record_ref");
- return NULL;
- }
-
- s_symbol *field = SX_AS_SYMBOL(subj_expr->next);
- if (field == NULL) {
- ir_read_error(st, list, "expected (record_ref ... <field name>)");
- return NULL;
- }
- return new(ctx) ir_dereference_record(subject, field->value());
-}
-
-static bool
-valid_texture_list_length(ir_texture_opcode op, s_list *list)
-{
- unsigned required_length = 7;
- if (op == ir_txf)
- required_length = 5;
- else if (op == ir_tex)
- required_length = 6;
-
- return list->length() == required_length;
-}
-
-static ir_texture *
-read_texture(_mesa_glsl_parse_state *st, s_list *list)
-{
- void *ctx = talloc_parent(st);
- s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
- assert(tag != NULL);
-
- ir_texture_opcode op = ir_texture::get_opcode(tag->value());
- if (op == (ir_texture_opcode) -1)
- return NULL;
-
- if (!valid_texture_list_length(op, list)) {
- ir_read_error(st, NULL, "invalid list size in (%s ...)", tag->value());
- return NULL;
- }
-
- ir_texture *tex = new(ctx) ir_texture(op);
-
- // Read sampler (must be a deref)
- s_expression *sampler_expr = (s_expression *) tag->next;
- ir_dereference *sampler = read_dereference(st, sampler_expr);
- if (sampler == NULL) {
- ir_read_error(st, NULL, "when reading sampler in (%s ...)", tag->value());
- return NULL;
- }
- tex->set_sampler(sampler);
-
- // Read coordinate (any rvalue)
- s_expression *coordinate_expr = (s_expression *) sampler_expr->next;
- tex->coordinate = read_rvalue(st, coordinate_expr);
- if (tex->coordinate == NULL) {
- ir_read_error(st, NULL, "when reading coordinate in (%s ...)",
- tag->value());
- return NULL;
- }
-
- // Read texel offset, i.e. (0 0 0)
- s_list *offset_list = SX_AS_LIST(coordinate_expr->next);
- if (offset_list == NULL || offset_list->length() != 3) {
- ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
- return NULL;
- }
- s_int *offset_x = SX_AS_INT(offset_list->subexpressions.head);
- s_int *offset_y = SX_AS_INT(offset_x->next);
- s_int *offset_z = SX_AS_INT(offset_y->next);
- if (offset_x == NULL || offset_y == NULL || offset_z == NULL) {
- ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
- return NULL;
- }
- tex->offsets[0] = offset_x->value();
- tex->offsets[1] = offset_y->value();
- tex->offsets[2] = offset_z->value();
-
- if (op == ir_txf) {
- s_expression *lod_expr = (s_expression *) offset_list->next;
- tex->lod_info.lod = read_rvalue(st, lod_expr);
- if (tex->lod_info.lod == NULL) {
- ir_read_error(st, NULL, "when reading LOD in (txf ...)");
- return NULL;
- }
- } else {
- s_expression *proj_expr = (s_expression *) offset_list->next;
- s_int *proj_as_int = SX_AS_INT(proj_expr);
- if (proj_as_int && proj_as_int->value() == 1) {
- tex->projector = NULL;
- } else {
- tex->projector = read_rvalue(st, proj_expr);
- if (tex->projector == NULL) {
- ir_read_error(st, NULL, "when reading projective divide in (%s ..)",
- tag->value());
- return NULL;
- }
- }
-
- s_list *shadow_list = SX_AS_LIST(proj_expr->next);
- if (shadow_list == NULL) {
- ir_read_error(st, NULL, "shadow comparitor must be a list");
- return NULL;
- }
- if (shadow_list->subexpressions.is_empty()) {
- tex->shadow_comparitor= NULL;
- } else {
- tex->shadow_comparitor = read_rvalue(st, shadow_list);
- if (tex->shadow_comparitor == NULL) {
- ir_read_error(st, NULL, "when reading shadow comparitor in (%s ..)",
- tag->value());
- return NULL;
- }
- }
- s_expression *lod_expr = (s_expression *) shadow_list->next;
-
- switch (op) {
- case ir_txb:
- tex->lod_info.bias = read_rvalue(st, lod_expr);
- if (tex->lod_info.bias == NULL) {
- ir_read_error(st, NULL, "when reading LOD bias in (txb ...)");
- return NULL;
- }
- break;
- case ir_txl:
- tex->lod_info.lod = read_rvalue(st, lod_expr);
- if (tex->lod_info.lod == NULL) {
- ir_read_error(st, NULL, "when reading LOD in (txl ...)");
- return NULL;
- }
- break;
- case ir_txd: {
- s_list *lod_list = SX_AS_LIST(lod_expr);
- if (lod_list->length() != 2) {
- ir_read_error(st, lod_expr, "expected (dPdx dPdy) in (txd ...)");
- return NULL;
- }
- s_expression *dx_expr = (s_expression *) lod_list->subexpressions.head;
- s_expression *dy_expr = (s_expression *) dx_expr->next;
-
- tex->lod_info.grad.dPdx = read_rvalue(st, dx_expr);
- if (tex->lod_info.grad.dPdx == NULL) {
- ir_read_error(st, NULL, "when reading dPdx in (txd ...)");
- return NULL;
- }
- tex->lod_info.grad.dPdy = read_rvalue(st, dy_expr);
- if (tex->lod_info.grad.dPdy == NULL) {
- ir_read_error(st, NULL, "when reading dPdy in (txd ...)");
- return NULL;
- }
- break;
- }
- default:
- // tex doesn't have any extra parameters and txf was handled earlier.
- break;
- };
- }
- return tex;
-}
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#pragma once
-#ifndef IR_READER_H
-#define IR_READER_H
-
-#include "ir.h"
-
-void _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
- const char *src);
-
-#endif /* IR_READER_H */
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_swizzle_swizzle.cpp
- *
- * Eliminates the second swizzle in a swizzle chain.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_optimization.h"
-#include "glsl_types.h"
-
-class ir_swizzle_swizzle_visitor : public ir_hierarchical_visitor {
-public:
- ir_swizzle_swizzle_visitor()
- {
- progress = false;
- }
-
- virtual ir_visitor_status visit_enter(ir_swizzle *);
-
- bool progress;
-};
-
-ir_visitor_status
-ir_swizzle_swizzle_visitor::visit_enter(ir_swizzle *ir)
-{
- int mask2[4];
-
- ir_swizzle *swiz2 = ir->val->as_swizzle();
- if (!swiz2)
- return visit_continue;
-
- memset(&mask2, 0, sizeof(mask2));
- if (swiz2->mask.num_components >= 1)
- mask2[0] = swiz2->mask.x;
- if (swiz2->mask.num_components >= 2)
- mask2[1] = swiz2->mask.y;
- if (swiz2->mask.num_components >= 3)
- mask2[2] = swiz2->mask.z;
- if (swiz2->mask.num_components >= 4)
- mask2[3] = swiz2->mask.w;
-
- if (ir->mask.num_components >= 1)
- ir->mask.x = mask2[ir->mask.x];
- if (ir->mask.num_components >= 2)
- ir->mask.y = mask2[ir->mask.y];
- if (ir->mask.num_components >= 3)
- ir->mask.z = mask2[ir->mask.z];
- if (ir->mask.num_components >= 4)
- ir->mask.w = mask2[ir->mask.w];
-
- ir->val = swiz2->val;
-
- this->progress = true;
-
- return visit_continue;
-}
-
-/**
- * Does a copy propagation pass on the code present in the instruction stream.
- */
-bool
-do_swizzle_swizzle(exec_list *instructions)
-{
- ir_swizzle_swizzle_visitor v;
-
- v.run(instructions);
-
- return v.progress;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_to_mesa.cpp
- *
- * Translates the IR to ARB_fragment_program text if possible,
- * printing the result
- */
-
-#include <stdio.h>
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_print_visitor.h"
-#include "ir_expression_flattening.h"
-#include "glsl_types.h"
-
-extern "C" {
-#include "shader/prog_instruction.h"
-#include "shader/prog_print.h"
-}
-
-/**
- * This struct is a corresponding struct to Mesa prog_src_register, with
- * wider fields.
- */
-typedef struct ir_to_mesa_src_reg {
- int file; /**< PROGRAM_* from Mesa */
- int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
- int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
- int negate; /**< NEGATE_XYZW mask from mesa */
- bool reladdr; /**< Register index should be offset by address reg. */
-} ir_to_mesa_src_reg;
-
-typedef struct ir_to_mesa_dst_reg {
- int file; /**< PROGRAM_* from Mesa */
- int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
- int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
-} ir_to_mesa_dst_reg;
-
-extern ir_to_mesa_src_reg ir_to_mesa_undef;
-
-class ir_to_mesa_instruction : public exec_node {
-public:
- enum prog_opcode op;
- ir_to_mesa_dst_reg dst_reg;
- ir_to_mesa_src_reg src_reg[3];
- /** Pointer to the ir source this tree came from for debugging */
- ir_instruction *ir;
-};
-
-class temp_entry : public exec_node {
-public:
- temp_entry(ir_variable *var, int file, int index)
- : file(file), index(index), var(var)
- {
- /* empty */
- }
-
- int file;
- int index;
- ir_variable *var; /* variable that maps to this, if any */
-};
-
-class ir_to_mesa_visitor : public ir_visitor {
-public:
- ir_to_mesa_visitor();
-
- int next_temp;
- int next_constant;
- int next_uniform;
-
- temp_entry *find_variable_storage(ir_variable *var);
-
- ir_to_mesa_src_reg get_temp(const glsl_type *type);
-
- struct ir_to_mesa_src_reg src_reg_for_float(float val);
-
- /**
- * \name Visit methods
- *
- * As typical for the visitor pattern, there must be one \c visit method for
- * each concrete subclass of \c ir_instruction. Virtual base classes within
- * the hierarchy should not have \c visit methods.
- */
- /*@{*/
- virtual void visit(ir_variable *);
- virtual void visit(ir_loop *);
- virtual void visit(ir_loop_jump *);
- virtual void visit(ir_function_signature *);
- virtual void visit(ir_function *);
- virtual void visit(ir_expression *);
- virtual void visit(ir_swizzle *);
- virtual void visit(ir_dereference_variable *);
- virtual void visit(ir_dereference_array *);
- virtual void visit(ir_dereference_record *);
- virtual void visit(ir_assignment *);
- virtual void visit(ir_constant *);
- virtual void visit(ir_call *);
- virtual void visit(ir_return *);
- virtual void visit(ir_texture *);
- virtual void visit(ir_if *);
- /*@}*/
-
- struct ir_to_mesa_src_reg result;
-
- /** List of temp_entry */
- exec_list variable_storage;
-
- /** List of ir_to_mesa_instruction */
- exec_list instructions;
-
- ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0);
-
- ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0,
- ir_to_mesa_src_reg src1);
-
- ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0,
- ir_to_mesa_src_reg src1,
- ir_to_mesa_src_reg src2);
-
- void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0);
-
- /* talloc context (the ) */
- void *ctx;
-};
-
-ir_to_mesa_src_reg ir_to_mesa_undef = {
- PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
-};
-
-ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
- PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
-};
-
-ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
- PROGRAM_ADDRESS, 0, WRITEMASK_X
-};
-
-static int swizzle_for_size(int size)
-{
- int size_swizzles[4] = {
- MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
- MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
- MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
- MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
- };
-
- return size_swizzles[size - 1];
-}
-
-/* This list should match up with builtin_variables.h */
-static const struct {
- const char *name;
- int file;
- int index;
-} builtin_var_to_mesa_reg[] = {
- /* core_vs */
- {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS},
- {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ},
-
- /* core_fs */
- {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS},
- {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE},
- {"gl_FragColor", PROGRAM_OUTPUT, FRAG_ATTRIB_COL0},
- {"gl_FragDepth", PROGRAM_UNDEFINED, FRAG_ATTRIB_WPOS}, /* FINISHME: WPOS.z */
-
- /* 110_deprecated_fs */
- {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
- {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1},
- {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC},
- {"gl_TexCoord", PROGRAM_INPUT, FRAG_ATTRIB_TEX0}, /* array */
-
- /* 110_deprecated_vs */
- {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS},
- {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL},
- {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0},
- {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1},
- {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0},
- {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1},
- {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2},
- {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3},
- {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4},
- {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5},
- {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6},
- {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7},
- {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */
- {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC},
- /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
- {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0},
- {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0},
- {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1},
- {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1},
- {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC},
-
- /* 130_vs */
- /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
-
- {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */
-};
-
-ir_to_mesa_instruction *
-ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0,
- ir_to_mesa_src_reg src1,
- ir_to_mesa_src_reg src2)
-{
- ir_to_mesa_instruction *inst = new(ctx) ir_to_mesa_instruction();
-
- inst->op = op;
- inst->dst_reg = dst;
- inst->src_reg[0] = src0;
- inst->src_reg[1] = src1;
- inst->src_reg[2] = src2;
- inst->ir = ir;
-
- this->instructions.push_tail(inst);
-
- return inst;
-}
-
-
-ir_to_mesa_instruction *
-ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0,
- ir_to_mesa_src_reg src1)
-{
- return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
-}
-
-ir_to_mesa_instruction *
-ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0)
-{
- return ir_to_mesa_emit_op3(ir, op, dst,
- src0, ir_to_mesa_undef, ir_to_mesa_undef);
-}
-
-inline ir_to_mesa_dst_reg
-ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
-{
- ir_to_mesa_dst_reg dst_reg;
-
- dst_reg.file = reg.file;
- dst_reg.index = reg.index;
- dst_reg.writemask = WRITEMASK_XYZW;
-
- return dst_reg;
-}
-
-/**
- * Emits Mesa scalar opcodes to produce unique answers across channels.
- *
- * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X
- * channel determines the result across all channels. So to do a vec4
- * of this operation, we want to emit a scalar per source channel used
- * to produce dest channels.
- */
-void
-ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
- enum prog_opcode op,
- ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0)
-{
- int i, j;
- int done_mask = ~dst.writemask;
-
- /* Mesa RCP is a scalar operation splatting results to all channels,
- * like ARB_fp/vp. So emit as many RCPs as necessary to cover our
- * dst channels.
- */
- for (i = 0; i < 4; i++) {
- int this_mask = (1 << i);
- ir_to_mesa_instruction *inst;
- ir_to_mesa_src_reg src = src0;
-
- if (done_mask & this_mask)
- continue;
-
- int src_swiz = GET_SWZ(src.swizzle, i);
- for (j = i + 1; j < 4; j++) {
- if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) {
- this_mask |= (1 << j);
- }
- }
- src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz,
- src_swiz, src_swiz);
-
- inst = ir_to_mesa_emit_op1(ir, op,
- dst,
- src);
- inst->dst_reg.writemask = this_mask;
- done_mask |= this_mask;
- }
-}
-
-struct ir_to_mesa_src_reg
-ir_to_mesa_visitor::src_reg_for_float(float val)
-{
- ir_to_mesa_src_reg src_reg;
-
- /* FINISHME: This will end up being _mesa_add_unnamed_constant,
- * which handles sharing values and sharing channels of vec4
- * constants for small values.
- */
- /* FINISHME: Do something with the constant values for now.
- */
- (void)val;
- src_reg.file = PROGRAM_CONSTANT;
- src_reg.index = this->next_constant++;
- src_reg.swizzle = SWIZZLE_NOOP;
-
- return src_reg;
-}
-
-/**
- * In the initial pass of codegen, we assign temporary numbers to
- * intermediate results. (not SSA -- variable assignments will reuse
- * storage). Actual register allocation for the Mesa VM occurs in a
- * pass over the Mesa IR later.
- */
-ir_to_mesa_src_reg
-ir_to_mesa_visitor::get_temp(const glsl_type *type)
-{
- ir_to_mesa_src_reg src_reg;
- int swizzle[4];
- int i;
-
- assert(!type->is_array());
-
- src_reg.file = PROGRAM_TEMPORARY;
- src_reg.index = type->matrix_columns;
- src_reg.reladdr = false;
-
- for (i = 0; i < type->vector_elements; i++)
- swizzle[i] = i;
- for (; i < 4; i++)
- swizzle[i] = type->vector_elements - 1;
- src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
- swizzle[2], swizzle[3]);
-
- return src_reg;
-}
-
-static int
-type_size(const struct glsl_type *type)
-{
- unsigned int i;
- int size;
-
- switch (type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_BOOL:
- if (type->is_matrix()) {
- return 4; /* FINISHME: Not all matrices are 4x4. */
- } else {
- /* Regardless of size of vector, it gets a vec4. This is bad
- * packing for things like floats, but otherwise arrays become a
- * mess. Hopefully a later pass over the code can pack scalars
- * down if appropriate.
- */
- return 1;
- }
- case GLSL_TYPE_ARRAY:
- return type_size(type->fields.array) * type->length;
- case GLSL_TYPE_STRUCT:
- size = 0;
- for (i = 0; i < type->length; i++) {
- size += type_size(type->fields.structure[i].type);
- }
- return size;
- default:
- assert(0);
- }
-}
-
-temp_entry *
-ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
-{
-
- temp_entry *entry;
-
- foreach_iter(exec_list_iterator, iter, this->variable_storage) {
- entry = (temp_entry *)iter.get();
-
- if (entry->var == var)
- return entry;
- }
-
- return NULL;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_variable *ir)
-{
- (void)ir;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_loop *ir)
-{
- assert(!ir->from);
- assert(!ir->to);
- assert(!ir->increment);
- assert(!ir->counter);
-
- ir_to_mesa_emit_op1(NULL, OPCODE_BGNLOOP,
- ir_to_mesa_undef_dst, ir_to_mesa_undef);
-
- visit_exec_list(&ir->body_instructions, this);
-
- ir_to_mesa_emit_op1(NULL, OPCODE_ENDLOOP,
- ir_to_mesa_undef_dst, ir_to_mesa_undef);
-}
-
-void
-ir_to_mesa_visitor::visit(ir_loop_jump *ir)
-{
- switch (ir->mode) {
- case ir_loop_jump::jump_break:
- ir_to_mesa_emit_op1(NULL, OPCODE_BRK,
- ir_to_mesa_undef_dst, ir_to_mesa_undef);
- break;
- case ir_loop_jump::jump_continue:
- ir_to_mesa_emit_op1(NULL, OPCODE_CONT,
- ir_to_mesa_undef_dst, ir_to_mesa_undef);
- break;
- }
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_function_signature *ir)
-{
- assert(0);
- (void)ir;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_function *ir)
-{
- /* Ignore function bodies other than main() -- we shouldn't see calls to
- * them since they should all be inlined before we get to ir_to_mesa.
- */
- if (strcmp(ir->name, "main") == 0) {
- const ir_function_signature *sig;
- exec_list empty;
-
- sig = ir->matching_signature(&empty);
-
- assert(sig);
-
- foreach_iter(exec_list_iterator, iter, sig->body) {
- ir_instruction *ir = (ir_instruction *)iter.get();
-
- ir->accept(this);
- }
- }
-}
-
-void
-ir_to_mesa_visitor::visit(ir_expression *ir)
-{
- unsigned int operand;
- struct ir_to_mesa_src_reg op[2];
- struct ir_to_mesa_src_reg result_src;
- struct ir_to_mesa_dst_reg result_dst;
- const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
- const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
- const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
-
- for (operand = 0; operand < ir->get_num_operands(); operand++) {
- this->result.file = PROGRAM_UNDEFINED;
- ir->operands[operand]->accept(this);
- if (this->result.file == PROGRAM_UNDEFINED) {
- ir_print_visitor v;
- printf("Failed to get tree for expression operand:\n");
- ir->operands[operand]->accept(&v);
- exit(1);
- }
- op[operand] = this->result;
-
- /* Only expression implemented for matrices yet */
- assert(!ir->operands[operand]->type->is_matrix() ||
- ir->operation == ir_binop_mul);
- }
-
- this->result.file = PROGRAM_UNDEFINED;
-
- /* Storage for our result. Ideally for an assignment we'd be using
- * the actual storage for the result here, instead.
- */
- result_src = get_temp(ir->type);
- /* convenience for the emit functions below. */
- result_dst = ir_to_mesa_dst_reg_from_src(result_src);
- /* Limit writes to the channels that will be used by result_src later.
- * This does limit this temp's use as a temporary for multi-instruction
- * sequences.
- */
- result_dst.writemask = (1 << ir->type->vector_elements) - 1;
-
- switch (ir->operation) {
- case ir_unop_logic_not:
- ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
- op[0], src_reg_for_float(0.0));
- break;
- case ir_unop_neg:
- op[0].negate = ~op[0].negate;
- result_src = op[0];
- break;
- case ir_unop_exp:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_EXP, result_dst, op[0]);
- break;
- case ir_unop_exp2:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
- break;
- case ir_unop_log:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
- break;
- case ir_unop_log2:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
- break;
- case ir_unop_sin:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
- break;
- case ir_unop_cos:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
- break;
- case ir_binop_add:
- ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
- break;
- case ir_binop_sub:
- ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
- break;
- case ir_binop_mul:
- if (ir->operands[0]->type->is_matrix() &&
- !ir->operands[1]->type->is_matrix()) {
- if (ir->operands[0]->type->is_scalar()) {
- ir_to_mesa_dst_reg dst_column = result_dst;
- ir_to_mesa_src_reg src_column = op[0];
- for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
- ir_to_mesa_emit_op2(ir, OPCODE_MUL,
- dst_column, src_column, op[1]);
- dst_column.index++;
- src_column.index++;
- }
- } else {
- ir_to_mesa_dst_reg dst_chan = result_dst;
- ir_to_mesa_src_reg src_column = op[0];
- ir_to_mesa_src_reg src_chan = op[1];
- for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
- dst_chan.writemask = (1 << i);
- src_chan.swizzle = MAKE_SWIZZLE4(i, i, i, i);
- ir_to_mesa_emit_op2(ir, OPCODE_MUL,
- dst_chan, src_column, src_chan);
- src_column.index++;
- }
- }
- } else {
- assert(!ir->operands[0]->type->is_matrix());
- assert(!ir->operands[1]->type->is_matrix());
- ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
- }
- break;
- case ir_binop_div:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[1]);
- ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], result_src);
- break;
-
- case ir_binop_less:
- ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
- break;
- case ir_binop_greater:
- ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
- break;
- case ir_binop_lequal:
- ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
- break;
- case ir_binop_gequal:
- ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
- break;
- case ir_binop_equal:
- ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
- break;
- case ir_binop_logic_xor:
- case ir_binop_nequal:
- ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
- break;
-
- case ir_binop_logic_or:
- /* This could be a saturated add and skip the SNE. */
- ir_to_mesa_emit_op2(ir, OPCODE_ADD,
- result_dst,
- op[0], op[1]);
-
- ir_to_mesa_emit_op2(ir, OPCODE_SNE,
- result_dst,
- result_src, src_reg_for_float(0.0));
- break;
-
- case ir_binop_logic_and:
- /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
- ir_to_mesa_emit_op2(ir, OPCODE_MUL,
- result_dst,
- op[0], op[1]);
- break;
-
- case ir_binop_dot:
- if (ir->operands[0]->type == vec4_type) {
- assert(ir->operands[1]->type == vec4_type);
- ir_to_mesa_emit_op2(ir, OPCODE_DP4,
- result_dst,
- op[0], op[1]);
- } else if (ir->operands[0]->type == vec3_type) {
- assert(ir->operands[1]->type == vec3_type);
- ir_to_mesa_emit_op2(ir, OPCODE_DP3,
- result_dst,
- op[0], op[1]);
- } else if (ir->operands[0]->type == vec2_type) {
- assert(ir->operands[1]->type == vec2_type);
- ir_to_mesa_emit_op2(ir, OPCODE_DP2,
- result_dst,
- op[0], op[1]);
- }
- break;
- case ir_unop_sqrt:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
- ir_to_mesa_emit_op1(ir, OPCODE_RCP, result_dst, result_src);
- break;
- case ir_unop_rsq:
- ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
- break;
- case ir_unop_i2f:
- /* Mesa IR lacks types, ints are stored as truncated floats. */
- result_src = op[0];
- break;
- case ir_unop_f2i:
- ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
- break;
- case ir_unop_f2b:
- ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
- result_src, src_reg_for_float(0.0));
- break;
- case ir_unop_trunc:
- ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
- break;
- case ir_unop_ceil:
- op[0].negate = ~op[0].negate;
- ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
- result_src.negate = ~result_src.negate;
- break;
- case ir_unop_floor:
- ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
- break;
- case ir_binop_min:
- ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
- break;
- case ir_binop_max:
- ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
- break;
- default:
- ir_print_visitor v;
- printf("Failed to get tree for expression:\n");
- ir->accept(&v);
- exit(1);
- break;
- }
-
- this->result = result_src;
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_swizzle *ir)
-{
- ir_to_mesa_src_reg src_reg;
- int i;
- int swizzle[4];
-
- /* Note that this is only swizzles in expressions, not those on the left
- * hand side of an assignment, which do write masking. See ir_assignment
- * for that.
- */
-
- ir->val->accept(this);
- src_reg = this->result;
- assert(src_reg.file != PROGRAM_UNDEFINED);
-
- for (i = 0; i < 4; i++) {
- if (i < ir->type->vector_elements) {
- switch (i) {
- case 0:
- swizzle[i] = ir->mask.x;
- break;
- case 1:
- swizzle[i] = ir->mask.y;
- break;
- case 2:
- swizzle[i] = ir->mask.z;
- break;
- case 3:
- swizzle[i] = ir->mask.w;
- break;
- }
- } else {
- /* If the type is smaller than a vec4, replicate the last
- * channel out.
- */
- swizzle[i] = ir->type->vector_elements - 1;
- }
- }
-
- src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
- swizzle[1],
- swizzle[2],
- swizzle[3]);
-
- this->result = src_reg;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
-{
- ir_to_mesa_src_reg src_reg;
- temp_entry *entry = find_variable_storage(ir->var);
- unsigned int i;
- bool var_in;
-
- if (!entry) {
- switch (ir->var->mode) {
- case ir_var_uniform:
- entry = new(ctx) temp_entry(ir->var, PROGRAM_UNIFORM,
- this->next_uniform);
- this->variable_storage.push_tail(entry);
-
- this->next_uniform += type_size(ir->var->type);
- break;
- case ir_var_in:
- case ir_var_out:
- case ir_var_inout:
- var_in = (ir->var->mode == ir_var_in ||
- ir->var->mode == ir_var_inout);
-
- for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
- bool in = builtin_var_to_mesa_reg[i].file == PROGRAM_INPUT;
-
- if (strcmp(ir->var->name, builtin_var_to_mesa_reg[i].name) == 0 &&
- !(var_in ^ in))
- break;
- }
- if (i == ARRAY_SIZE(builtin_var_to_mesa_reg)) {
- printf("Failed to find builtin for %s variable %s\n",
- var_in ? "in" : "out",
- ir->var->name);
- abort();
- }
- entry = new(ctx) temp_entry(ir->var,
- builtin_var_to_mesa_reg[i].file,
- builtin_var_to_mesa_reg[i].index);
- break;
- case ir_var_auto:
- entry = new(ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
- this->next_temp);
- this->variable_storage.push_tail(entry);
-
- next_temp += type_size(ir->var->type);
- break;
- }
-
- if (!entry) {
- printf("Failed to make storage for %s\n", ir->var->name);
- exit(1);
- }
- }
-
- src_reg.file = entry->file;
- src_reg.index = entry->index;
- /* If the type is smaller than a vec4, replicate the last channel out. */
- src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
- src_reg.reladdr = false;
- src_reg.negate = 0;
-
- this->result = src_reg;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_dereference_array *ir)
-{
- ir_constant *index;
- ir_to_mesa_src_reg src_reg;
-
- index = ir->array_index->constant_expression_value();
-
- /* By the time we make it to this stage, matrices should be broken down
- * to vectors.
- */
- assert(!ir->type->is_matrix());
-
- ir->array->accept(this);
- src_reg = this->result;
-
- if (src_reg.file == PROGRAM_INPUT ||
- src_reg.file == PROGRAM_OUTPUT) {
- assert(index); /* FINISHME: Handle variable indexing of builtins. */
-
- src_reg.index += index->value.i[0];
- } else {
- if (index) {
- src_reg.index += index->value.i[0];
- } else {
- ir_to_mesa_src_reg array_base = this->result;
- /* Variable index array dereference. It eats the "vec4" of the
- * base of the array and an index that offsets the Mesa register
- * index.
- */
- ir->array_index->accept(this);
-
- /* FINISHME: This doesn't work when we're trying to do the LHS
- * of an assignment.
- */
- src_reg.reladdr = true;
- ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
- this->result);
-
- this->result = get_temp(ir->type);
- ir_to_mesa_emit_op1(ir, OPCODE_MOV,
- ir_to_mesa_dst_reg_from_src(this->result),
- src_reg);
- }
- }
-
- /* If the type is smaller than a vec4, replicate the last channel out. */
- src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
-
- this->result = src_reg;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_dereference_record *ir)
-{
- unsigned int i;
- const glsl_type *struct_type = ir->record->type;
- int offset = 0;
-
- ir->record->accept(this);
-
- for (i = 0; i < struct_type->length; i++) {
- if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
- break;
- offset += type_size(struct_type->fields.structure[i].type);
- }
- this->result.index += offset;
-}
-
-/**
- * We want to be careful in assignment setup to hit the actual storage
- * instead of potentially using a temporary like we might with the
- * ir_dereference handler.
- *
- * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
- * should only see potentially one variable array index of a vector,
- * and one swizzle, before getting to actual vec4 storage. So handle
- * those, then go use ir_dereference to handle the rest.
- */
-static struct ir_to_mesa_dst_reg
-get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
-{
- struct ir_to_mesa_dst_reg dst_reg;
- ir_dereference *deref;
- ir_swizzle *swiz;
-
- /* Use the rvalue deref handler for the most part. We'll ignore
- * swizzles in it and write swizzles using writemask, though.
- */
- ir->accept(v);
- dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
-
- if ((deref = ir->as_dereference())) {
- ir_dereference_array *deref_array = ir->as_dereference_array();
- assert(!deref_array || deref_array->array->type->is_array());
-
- ir->accept(v);
- } else if ((swiz = ir->as_swizzle())) {
- dst_reg.writemask = 0;
- if (swiz->mask.num_components >= 1)
- dst_reg.writemask |= (1 << swiz->mask.x);
- if (swiz->mask.num_components >= 2)
- dst_reg.writemask |= (1 << swiz->mask.y);
- if (swiz->mask.num_components >= 3)
- dst_reg.writemask |= (1 << swiz->mask.z);
- if (swiz->mask.num_components >= 4)
- dst_reg.writemask |= (1 << swiz->mask.w);
- }
-
- return dst_reg;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_assignment *ir)
-{
- struct ir_to_mesa_dst_reg l;
- struct ir_to_mesa_src_reg r;
-
- assert(!ir->lhs->type->is_matrix());
- assert(!ir->lhs->type->is_array());
- assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
-
- l = get_assignment_lhs(ir->lhs, this);
-
- ir->rhs->accept(this);
- r = this->result;
- assert(l.file != PROGRAM_UNDEFINED);
- assert(r.file != PROGRAM_UNDEFINED);
-
- if (ir->condition) {
- ir_constant *condition_constant;
-
- condition_constant = ir->condition->constant_expression_value();
-
- assert(condition_constant && condition_constant->value.b[0]);
- }
-
- ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_constant *ir)
-{
- ir_to_mesa_src_reg src_reg;
-
- assert(ir->type->base_type == GLSL_TYPE_FLOAT ||
- ir->type->base_type == GLSL_TYPE_UINT ||
- ir->type->base_type == GLSL_TYPE_INT ||
- ir->type->base_type == GLSL_TYPE_BOOL);
-
- /* FINISHME: This will end up being _mesa_add_unnamed_constant,
- * which handles sharing values and sharing channels of vec4
- * constants for small values.
- */
- /* FINISHME: Do something with the constant values for now.
- */
- src_reg.file = PROGRAM_CONSTANT;
- src_reg.index = this->next_constant;
- src_reg.swizzle = SWIZZLE_NOOP;
- src_reg.reladdr = false;
- src_reg.negate = 0;
-
- this->next_constant += type_size(ir->type);
-
- this->result = src_reg;
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_call *ir)
-{
- printf("Can't support call to %s\n", ir->callee_name());
- exit(1);
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_texture *ir)
-{
- assert(0);
-
- ir->coordinate->accept(this);
-}
-
-void
-ir_to_mesa_visitor::visit(ir_return *ir)
-{
- assert(0);
-
- ir->get_value()->accept(this);
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_if *ir)
-{
- ir_to_mesa_instruction *if_inst, *else_inst = NULL;
-
- ir->condition->accept(this);
- assert(this->result.file != PROGRAM_UNDEFINED);
-
- if_inst = ir_to_mesa_emit_op1(ir->condition,
- OPCODE_IF, ir_to_mesa_undef_dst,
- this->result);
-
- this->instructions.push_tail(if_inst);
-
- visit_exec_list(&ir->then_instructions, this);
-
- if (!ir->else_instructions.is_empty()) {
- else_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ELSE,
- ir_to_mesa_undef_dst,
- ir_to_mesa_undef);
- visit_exec_list(&ir->then_instructions, this);
- }
-
- if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
- ir_to_mesa_undef_dst, ir_to_mesa_undef);
-}
-
-ir_to_mesa_visitor::ir_to_mesa_visitor()
-{
- result.file = PROGRAM_UNDEFINED;
- next_temp = 1;
- next_constant = 0;
- next_uniform = 0;
-}
-
-static struct prog_src_register
-mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
-{
- struct prog_src_register mesa_reg;
-
- mesa_reg.File = reg.file;
- assert(reg.index < (1 << INST_INDEX_BITS) - 1);
- mesa_reg.Index = reg.index;
- mesa_reg.Swizzle = reg.swizzle;
- mesa_reg.RelAddr = reg.reladdr;
-
- return mesa_reg;
-}
-
-static void
-set_branchtargets(struct prog_instruction *mesa_instructions,
- int num_instructions)
-{
- int if_count = 0, loop_count;
- int *if_stack, *loop_stack;
- int if_stack_pos = 0, loop_stack_pos = 0;
- int i, j;
-
- for (i = 0; i < num_instructions; i++) {
- switch (mesa_instructions[i].Opcode) {
- case OPCODE_IF:
- if_count++;
- break;
- case OPCODE_BGNLOOP:
- loop_count++;
- break;
- case OPCODE_BRK:
- case OPCODE_CONT:
- mesa_instructions[i].BranchTarget = -1;
- break;
- default:
- break;
- }
- }
-
- if_stack = (int *)calloc(if_count, sizeof(*if_stack));
- loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
-
- for (i = 0; i < num_instructions; i++) {
- switch (mesa_instructions[i].Opcode) {
- case OPCODE_IF:
- if_stack[if_stack_pos] = i;
- if_stack_pos++;
- break;
- case OPCODE_ELSE:
- mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
- if_stack[if_stack_pos - 1] = i;
- break;
- case OPCODE_ENDIF:
- mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
- if_stack_pos--;
- break;
- case OPCODE_BGNLOOP:
- loop_stack[loop_stack_pos] = i;
- loop_stack_pos++;
- break;
- case OPCODE_ENDLOOP:
- loop_stack_pos--;
- /* Rewrite any breaks/conts at this nesting level (haven't
- * already had a BranchTarget assigned) to point to the end
- * of the loop.
- */
- for (j = loop_stack[loop_stack_pos]; j < i; j++) {
- if (mesa_instructions[j].Opcode == OPCODE_BRK ||
- mesa_instructions[j].Opcode == OPCODE_CONT) {
- if (mesa_instructions[j].BranchTarget == -1) {
- mesa_instructions[j].BranchTarget = i;
- }
- }
- }
- /* The loop ends point at each other. */
- mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
- mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
- default:
- break;
- }
- }
-
- free(if_stack);
-}
-
-static void
-print_program(struct prog_instruction *mesa_instructions,
- ir_instruction **mesa_instruction_annotation,
- int num_instructions)
-{
- ir_instruction *last_ir = NULL;
- int i;
-
- for (i = 0; i < num_instructions; i++) {
- struct prog_instruction *mesa_inst = mesa_instructions + i;
- ir_instruction *ir = mesa_instruction_annotation[i];
-
- if (last_ir != ir && ir) {
- ir_print_visitor print;
- ir->accept(&print);
- printf("\n");
- last_ir = ir;
- }
-
- _mesa_print_instruction(mesa_inst);
- }
-}
-
-void
-do_ir_to_mesa(exec_list *instructions)
-{
- ir_to_mesa_visitor v;
- struct prog_instruction *mesa_instructions, *mesa_inst;
- ir_instruction **mesa_instruction_annotation;
- int i;
-
- v.ctx = talloc_new(NULL);
- visit_exec_list(instructions, &v);
-
- int num_instructions = 0;
- foreach_iter(exec_list_iterator, iter, v.instructions) {
- num_instructions++;
- }
-
- mesa_instructions =
- (struct prog_instruction *)calloc(num_instructions,
- sizeof(*mesa_instructions));
- mesa_instruction_annotation =
- (ir_instruction **)calloc(num_instructions,
- sizeof(*mesa_instruction_annotation));
-
- mesa_inst = mesa_instructions;
- i = 0;
- foreach_iter(exec_list_iterator, iter, v.instructions) {
- ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
-
- mesa_inst->Opcode = inst->op;
- mesa_inst->DstReg.File = inst->dst_reg.file;
- mesa_inst->DstReg.Index = inst->dst_reg.index;
- mesa_inst->DstReg.CondMask = COND_TR;
- mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
- mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
- mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
- mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
- mesa_instruction_annotation[i] = inst->ir;
-
- mesa_inst++;
- i++;
- }
-
- set_branchtargets(mesa_instructions, num_instructions);
- print_program(mesa_instructions, mesa_instruction_annotation, num_instructions);
-
- free(mesa_instruction_annotation);
- talloc_free(v.ctx);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_validate.cpp
- *
- * Attempts to verify that various invariants of the IR tree are true.
- *
- * In particular, at the moment it makes sure that no single
- * ir_instruction node except for ir_variable appears multiple times
- * in the ir tree. ir_variable does appear multiple times: Once as a
- * declaration in an exec_list, and multiple times as the endpoint of
- * a dereference chain.
- */
-
-#include <inttypes.h>
-#include "ir.h"
-#include "ir_hierarchical_visitor.h"
-#include "hash_table.h"
-
-static unsigned int hash_func(const void *key)
-{
- return (unsigned int)(uintptr_t)key;
-}
-
-static int hash_compare_func(const void *key1, const void *key2)
-{
- return key1 == key2 ? 0 : 1;
-}
-
-
-class ir_validate : public ir_hierarchical_visitor {
-public:
- ir_validate()
- {
- this->ht = hash_table_ctor(0, hash_func, hash_compare_func);
-
- this->callback = ir_validate::validate_ir;
- this->data = ht;
- }
-
- ~ir_validate()
- {
- hash_table_dtor(this->ht);
- }
-
- virtual ir_visitor_status visit(ir_variable *v);
-
- static void validate_ir(ir_instruction *ir, void *data);
-
- struct hash_table *ht;
-};
-
-ir_visitor_status
-ir_validate::visit(ir_variable *ir)
-{
- /* An ir_variable is the one thing that can (and will) appear multiple times
- * in an IR tree.
- */
- (void) ir;
- return visit_continue;
-}
-
-void
-ir_validate::validate_ir(ir_instruction *ir, void *data)
-{
- struct hash_table *ht = (struct hash_table *) data;
-
- if (hash_table_find(ht, ir)) {
- printf("Instruction node present twice in ir tree:\n");
- ir->print();
- printf("\n");
- abort();
- }
- hash_table_insert(ht, ir, ir);
-}
-
-void
-validate_ir_tree(exec_list *instructions)
-{
- ir_validate v;
-
- v.run(instructions);
-}
+++ /dev/null
-/*
- * 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 "ir.h"
-#include "glsl_parser_extras.h"
-#include "glsl_symbol_table.h"
-#include "builtin_variables.h"
-
-#ifndef Elements
-#define Elements(x) (sizeof(x)/sizeof(*(x)))
-#endif
-
-static ir_variable *
-add_variable(const char *name, enum ir_variable_mode mode, int slot,
- const glsl_type *type, exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- ir_variable *var = new(symtab) ir_variable(type, name);
-
- var->mode = mode;
- switch (var->mode) {
- case ir_var_in:
- var->shader_in = true;
- var->read_only = true;
- break;
- case ir_var_inout:
- var->shader_in = true;
- var->shader_out = true;
- break;
- case ir_var_out:
- var->shader_out = true;
- break;
- case ir_var_uniform:
- var->shader_in = true;
- var->read_only = true;
- break;
- default:
- assert(0);
- break;
- }
-
- var->location = slot;
-
- /* Once the variable is created an initialized, add it to the symbol table
- * and add the declaration to the IR stream.
- */
- instructions->push_tail(var);
-
- symtab->add_variable(var->name, var);
- return var;
-}
-
-
-static void
-add_builtin_variable(const builtin_variable *proto, exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- /* Create a new variable declaration from the description supplied by
- * the caller.
- */
- const glsl_type *const type = symtab->get_type(proto->type);
-
- assert(type != NULL);
-
- add_variable(proto->name, proto->mode, proto->slot, type, instructions,
- symtab);
-}
-
-
-static void
-generate_110_uniforms(exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- for (unsigned i = 0
- ; i < Elements(builtin_110_deprecated_uniforms)
- ; i++) {
- add_builtin_variable(& builtin_110_deprecated_uniforms[i],
- instructions, symtab);
- }
-
- /* FINISHME: The size of this array is implementation dependent based on the
- * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports
- * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4
- * FINISHME: for now.
- */
- const glsl_type *const mat4_array_type =
- glsl_type::get_array_instance(symtab, glsl_type::mat4_type, 4);
-
- add_variable("gl_TextureMatrix", ir_var_uniform, -1, mat4_array_type,
- instructions, symtab);
-
- /* FINISHME: Add support for gl_DepthRangeParameters */
- /* FINISHME: Add support for gl_ClipPlane[] */
- /* FINISHME: Add support for gl_PointParameters */
-
- /* FINISHME: Add support for gl_MaterialParameters
- * FINISHME: (glFrontMaterial, glBackMaterial)
- */
-
- /* FINISHME: The size of this array is implementation dependent based on the
- * FINISHME: value of GL_MAX_TEXTURE_LIGHTS. GL_MAX_TEXTURE_LIGHTS must be
- * FINISHME: at least 8, so hard-code 8 for now.
- */
- const glsl_type *const light_source_array_type =
- glsl_type::get_array_instance(symtab,
- symtab->get_type("gl_LightSourceParameters"), 8);
-
- add_variable("gl_LightSource", ir_var_uniform, -1, light_source_array_type,
- instructions, symtab);
-
- /* FINISHME: Add support for gl_LightModel */
- /* FINISHME: Add support for gl_FrontLightProduct[], gl_BackLightProduct[] */
- /* FINISHME: Add support for gl_TextureEnvColor[] */
- /* FINISHME: Add support for gl_ObjectPlane*[], gl_EyePlane*[] */
- /* FINISHME: Add support for gl_Fog */
-}
-
-static void
-generate_110_vs_variables(exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
- add_builtin_variable(& builtin_core_vs_variables[i],
- instructions, symtab);
- }
-
- for (unsigned i = 0
- ; i < Elements(builtin_110_deprecated_vs_variables)
- ; i++) {
- add_builtin_variable(& builtin_110_deprecated_vs_variables[i],
- instructions, symtab);
- }
- generate_110_uniforms(instructions, symtab);
-
- /* FINISHME: The size of this array is implementation dependent based on the
- * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports
- * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4
- * FINISHME: for now.
- */
- const glsl_type *const vec4_array_type =
- glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4);
-
- add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type,
- instructions, symtab);
-}
-
-
-static void
-generate_120_vs_variables(exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- /* GLSL version 1.20 did not add any built-in variables in the vertex
- * shader.
- */
- generate_110_vs_variables(instructions, symtab);
-}
-
-
-static void
-generate_130_vs_variables(exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- void *ctx = symtab;
- generate_120_vs_variables(instructions, symtab);
-
- for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) {
- add_builtin_variable(& builtin_130_vs_variables[i],
- instructions, symtab);
- }
-
- /* FINISHME: The size of this array is implementation dependent based on
- * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
- */
- const glsl_type *const clip_distance_array_type =
- glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
-
- /* FINISHME: gl_ClipDistance needs a real location assigned. */
- add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type,
- instructions, symtab);
-
-}
-
-
-static void
-initialize_vs_variables(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
-
- switch (state->language_version) {
- case 110:
- generate_110_vs_variables(instructions, state->symbols);
- break;
- case 120:
- generate_120_vs_variables(instructions, state->symbols);
- break;
- case 130:
- generate_130_vs_variables(instructions, state->symbols);
- break;
- }
-}
-
-static void
-generate_110_fs_variables(exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
- add_builtin_variable(& builtin_core_fs_variables[i],
- instructions, symtab);
- }
-
- for (unsigned i = 0
- ; i < Elements(builtin_110_deprecated_fs_variables)
- ; i++) {
- add_builtin_variable(& builtin_110_deprecated_fs_variables[i],
- instructions, symtab);
- }
- generate_110_uniforms(instructions, symtab);
-
- /* FINISHME: The size of this array is implementation dependent based on the
- * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports
- * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4
- * FINISHME: for now.
- */
- const glsl_type *const vec4_array_type =
- glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4);
-
- add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type,
- instructions, symtab);
-}
-
-
-static void
-generate_ARB_draw_buffers_fs_variables(exec_list *instructions,
- glsl_symbol_table *symtab, bool warn)
-{
- /* FINISHME: The size of this array is implementation dependent based on the
- * FINISHME: value of GL_MAX_DRAW_BUFFERS. GL_MAX_DRAW_BUFFERS must be
- * FINISHME: at least 1, so hard-code 1 for now.
- */
- const glsl_type *const vec4_array_type =
- glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 1);
-
- ir_variable *const fd =
- add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0,
- vec4_array_type, instructions, symtab);
-
- if (warn)
- fd->warn_extension = "GL_ARB_draw_buffers";
-}
-
-
-static void
-generate_120_fs_variables(exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- generate_110_fs_variables(instructions, symtab);
- generate_ARB_draw_buffers_fs_variables(instructions, symtab, false);
-}
-
-static void
-generate_130_fs_variables(exec_list *instructions,
- glsl_symbol_table *symtab)
-{
- void *ctx = symtab;
- generate_120_fs_variables(instructions, symtab);
-
- /* FINISHME: The size of this array is implementation dependent based on
- * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
- */
- const glsl_type *const clip_distance_array_type =
- glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
-
- /* FINISHME: gl_ClipDistance needs a real location assigned. */
- add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type,
- instructions, symtab);
-}
-
-static void
-initialize_fs_variables(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
-
- switch (state->language_version) {
- case 110:
- generate_110_fs_variables(instructions, state->symbols);
- break;
- case 120:
- generate_120_fs_variables(instructions, state->symbols);
- break;
- case 130:
- generate_130_fs_variables(instructions, state->symbols);
- break;
- }
-
-
- /* Since GL_ARB_draw_buffers is included in GLSL 1.20 and later, we
- * can basically ignore any extension settings for it.
- */
- if (state->language_version < 120) {
- if (state->ARB_draw_buffers_enable) {
- generate_ARB_draw_buffers_fs_variables(instructions, state->symbols,
- state->ARB_draw_buffers_warn);
- }
- }
-}
-
-void
-_mesa_glsl_initialize_variables(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- switch (state->target) {
- case vertex_shader:
- initialize_vs_variables(instructions, state);
- break;
- case geometry_shader:
- break;
- case fragment_shader:
- initialize_fs_variables(instructions, state);
- break;
- case ir_shader:
- fprintf(stderr, "ir reader has no builtin variables");
- exit(1);
- break;
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file ir_vec_index_to_swizzle.cpp
- *
- * Turns constant indexing into vector types to swizzles. This will
- * let other swizzle-aware optimization passes catch these constructs,
- * and codegen backends not have to worry about this case.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_optimization.h"
-#include "glsl_types.h"
-
-/**
- * Visitor class for replacing expressions with ir_constant values.
- */
-
-class ir_vec_index_to_swizzle_visitor : public ir_hierarchical_visitor {
-public:
- ir_vec_index_to_swizzle_visitor()
- {
- progress = false;
- }
-
- ir_rvalue *convert_vec_index_to_swizzle(ir_rvalue *val);
-
- virtual ir_visitor_status visit_enter(ir_expression *);
- virtual ir_visitor_status visit_enter(ir_swizzle *);
- virtual ir_visitor_status visit_enter(ir_assignment *);
- virtual ir_visitor_status visit_enter(ir_return *);
- virtual ir_visitor_status visit_enter(ir_call *);
- virtual ir_visitor_status visit_enter(ir_if *);
-
- bool progress;
-};
-
-ir_rvalue *
-ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir)
-{
- ir_dereference_array *deref = ir->as_dereference_array();
- ir_constant *ir_constant;
-
- if (!deref)
- return ir;
-
- if (deref->array->type->is_matrix() || deref->array->type->is_array())
- return ir;
-
- assert(deref->array_index->type->base_type == GLSL_TYPE_INT);
- ir_constant = deref->array_index->constant_expression_value();
- if (!ir_constant)
- return ir;
-
- void *ctx = talloc_parent(ir);
- this->progress = true;
- return new(ctx) ir_swizzle(deref->array,
- ir_constant->value.i[0], 0, 0, 0, 1);
-}
-
-ir_visitor_status
-ir_vec_index_to_swizzle_visitor::visit_enter(ir_expression *ir)
-{
- unsigned int i;
-
- for (i = 0; i < ir->get_num_operands(); i++) {
- ir->operands[i] = convert_vec_index_to_swizzle(ir->operands[i]);
- }
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_vec_index_to_swizzle_visitor::visit_enter(ir_swizzle *ir)
-{
- /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which
- * the result of indexing a vector is. But maybe at some point we'll end up
- * using swizzling of scalars for vector construction.
- */
- ir->val = convert_vec_index_to_swizzle(ir->val);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir)
-{
- ir->lhs = convert_vec_index_to_swizzle(ir->lhs);
- ir->rhs = convert_vec_index_to_swizzle(ir->rhs);
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir)
-{
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param = (ir_rvalue *)iter.get();
- ir_rvalue *new_param = convert_vec_index_to_swizzle(param);
-
- if (new_param != param) {
- param->insert_before(new_param);
- param->remove();
- }
- }
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_vec_index_to_swizzle_visitor::visit_enter(ir_return *ir)
-{
- if (ir->value) {
- ir->value = convert_vec_index_to_swizzle(ir->value);
- }
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_vec_index_to_swizzle_visitor::visit_enter(ir_if *ir)
-{
- ir->condition = convert_vec_index_to_swizzle(ir->condition);
-
- return visit_continue;
-}
-
-bool
-do_vec_index_to_swizzle(exec_list *instructions)
-{
- ir_vec_index_to_swizzle_visitor v;
-
- v.run(instructions);
-
- return false;
-}
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#pragma once
-#ifndef IR_VISITOR_H
-#define IR_VISITOR_H
-
-/**
- * Abstract base class of visitors of IR instruction trees
- */
-class ir_visitor {
-public:
- virtual ~ir_visitor()
- {
- /* empty */
- }
-
- /**
- * \name Visit methods
- *
- * As typical for the visitor pattern, there must be one \c visit method for
- * each concrete subclass of \c ir_instruction. Virtual base classes within
- * the hierarchy should not have \c visit methods.
- */
- /*@{*/
- virtual void visit(class ir_variable *) = 0;
- virtual void visit(class ir_function_signature *) = 0;
- virtual void visit(class ir_function *) = 0;
- virtual void visit(class ir_expression *) = 0;
- virtual void visit(class ir_texture *) = 0;
- virtual void visit(class ir_swizzle *) = 0;
- virtual void visit(class ir_dereference_variable *) = 0;
- virtual void visit(class ir_dereference_array *) = 0;
- virtual void visit(class ir_dereference_record *) = 0;
- virtual void visit(class ir_assignment *) = 0;
- virtual void visit(class ir_constant *) = 0;
- virtual void visit(class ir_call *) = 0;
- virtual void visit(class ir_return *) = 0;
- virtual void visit(class ir_if *) = 0;
- virtual void visit(class ir_loop *) = 0;
- virtual void visit(class ir_loop_jump *) = 0;
- /*@}*/
-};
-
-#endif /* IR_VISITOR_H */
+++ /dev/null
-/*
- * 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.
- */
-
-/**
- * \file linker.cpp
- * GLSL linker implementation
- *
- * Given a set of shaders that are to be linked to generate a final program,
- * there are three distinct stages.
- *
- * In the first stage shaders are partitioned into groups based on the shader
- * type. All shaders of a particular type (e.g., vertex shaders) are linked
- * together.
- *
- * - Undefined references in each shader are resolve to definitions in
- * another shader.
- * - Types and qualifiers of uniforms, outputs, and global variables defined
- * in multiple shaders with the same name are verified to be the same.
- * - Initializers for uniforms and global variables defined
- * in multiple shaders with the same name are verified to be the same.
- *
- * The result, in the terminology of the GLSL spec, is a set of shader
- * executables for each processing unit.
- *
- * After the first stage is complete, a series of semantic checks are performed
- * on each of the shader executables.
- *
- * - Each shader executable must define a \c main function.
- * - Each vertex shader executable must write to \c gl_Position.
- * - Each fragment shader executable must write to either \c gl_FragData or
- * \c gl_FragColor.
- *
- * In the final stage individual shader executables are linked to create a
- * complete exectuable.
- *
- * - Types of uniforms defined in multiple shader stages with the same name
- * are verified to be the same.
- * - Initializers for uniforms defined in multiple shader stages with the
- * same name are verified to be the same.
- * - Types and qualifiers of outputs defined in one stage are verified to
- * be the same as the types and qualifiers of inputs defined with the same
- * name in a later stage.
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-#include <cstdlib>
-#include <cstdio>
-#include <cstdarg>
-
-extern "C" {
-#include <talloc.h>
-}
-
-#include "main/mtypes.h"
-#include "glsl_symbol_table.h"
-#include "glsl_parser_extras.h"
-#include "ir.h"
-#include "ir_optimization.h"
-#include "program.h"
-#include "hash_table.h"
-
-/**
- * Visitor that determines whether or not a variable is ever written.
- */
-class find_assignment_visitor : public ir_hierarchical_visitor {
-public:
- find_assignment_visitor(const char *name)
- : name(name), found(false)
- {
- /* empty */
- }
-
- virtual ir_visitor_status visit_enter(ir_assignment *ir)
- {
- ir_variable *const var = ir->lhs->variable_referenced();
-
- if (strcmp(name, var->name) == 0) {
- found = true;
- return visit_stop;
- }
-
- return visit_continue_with_parent;
- }
-
- bool variable_found()
- {
- return found;
- }
-
-private:
- const char *name; /**< Find writes to a variable with this name. */
- bool found; /**< Was a write to the variable found? */
-};
-
-
-void
-linker_error_printf(glsl_program *prog, const char *fmt, ...)
-{
- va_list ap;
-
- prog->InfoLog = talloc_strdup_append(prog->InfoLog, "error: ");
- va_start(ap, fmt);
- prog->InfoLog = talloc_vasprintf_append(prog->InfoLog, fmt, ap);
- va_end(ap);
-}
-
-
-void
-invalidate_variable_locations(glsl_shader *sh, enum ir_variable_mode mode,
- int generic_base)
-{
- foreach_list(node, &sh->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
- if ((var == NULL) || (var->mode != (unsigned) mode))
- continue;
-
- /* Only assign locations for generic attributes / varyings / etc.
- */
- if (var->location >= generic_base)
- var->location = -1;
- }
-}
-
-
-/**
- * Determine the number of attribute slots required for a particular type
- *
- * This code is here because it implements the language rules of a specific
- * GLSL version. Since it's a property of the language and not a property of
- * types in general, it doesn't really belong in glsl_type.
- */
-unsigned
-count_attribute_slots(const glsl_type *t)
-{
- /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
- *
- * "A scalar input counts the same amount against this limit as a vec4,
- * so applications may want to consider packing groups of four
- * unrelated float inputs together into a vector to better utilize the
- * capabilities of the underlying hardware. A matrix input will use up
- * multiple locations. The number of locations used will equal the
- * number of columns in the matrix."
- *
- * The spec does not explicitly say how arrays are counted. However, it
- * should be safe to assume the total number of slots consumed by an array
- * is the number of entries in the array multiplied by the number of slots
- * consumed by a single element of the array.
- */
-
- if (t->is_array())
- return t->array_size() * count_attribute_slots(t->element_type());
-
- if (t->is_matrix())
- return t->matrix_columns;
-
- return 1;
-}
-
-
-/**
- * Verify that a vertex shader executable meets all semantic requirements
- *
- * \param shader Vertex shader executable to be verified
- */
-bool
-validate_vertex_shader_executable(struct glsl_program *prog,
- struct glsl_shader *shader)
-{
- if (shader == NULL)
- return true;
-
- if (!shader->symbols->get_function("main")) {
- linker_error_printf(prog, "vertex shader lacks `main'\n");
- return false;
- }
-
- find_assignment_visitor find("gl_Position");
- find.run(&shader->ir);
- if (!find.variable_found()) {
- linker_error_printf(prog,
- "vertex shader does not write to `gl_Position'\n");
- return false;
- }
-
- return true;
-}
-
-
-/**
- * Verify that a fragment shader executable meets all semantic requirements
- *
- * \param shader Fragment shader executable to be verified
- */
-bool
-validate_fragment_shader_executable(struct glsl_program *prog,
- struct glsl_shader *shader)
-{
- if (shader == NULL)
- return true;
-
- if (!shader->symbols->get_function("main")) {
- linker_error_printf(prog, "fragment shader lacks `main'\n");
- return false;
- }
-
- find_assignment_visitor frag_color("gl_FragColor");
- find_assignment_visitor frag_data("gl_FragData");
-
- frag_color.run(&shader->ir);
- frag_data.run(&shader->ir);
-
- if (!frag_color.variable_found() && !frag_data.variable_found()) {
- linker_error_printf(prog, "fragment shader does not write to "
- "`gl_FragColor' or `gl_FragData'\n");
- return false;
- }
-
- if (frag_color.variable_found() && frag_data.variable_found()) {
- linker_error_printf(prog, "fragment shader writes to both "
- "`gl_FragColor' and `gl_FragData'\n");
- return false;
- }
-
- return true;
-}
-
-
-/**
- * Perform validation of uniforms used across multiple shader stages
- */
-bool
-cross_validate_uniforms(struct glsl_program *prog)
-{
- /* Examine all of the uniforms in all of the shaders and cross validate
- * them.
- */
- glsl_symbol_table uniforms;
- for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
- foreach_list(node, &prog->_LinkedShaders[i]->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
- if ((var == NULL) || (var->mode != ir_var_uniform))
- continue;
-
- /* If a uniform with this name has already been seen, verify that the
- * new instance has the same type. In addition, if the uniforms have
- * initializers, the values of the initializers must be the same.
- */
- ir_variable *const existing = uniforms.get_variable(var->name);
- if (existing != NULL) {
- if (var->type != existing->type) {
- linker_error_printf(prog, "uniform `%s' declared as type "
- "`%s' and type `%s'\n",
- var->name, var->type->name,
- existing->type->name);
- return false;
- }
-
- if (var->constant_value != NULL) {
- if (existing->constant_value != NULL) {
- if (!var->constant_value->has_value(existing->constant_value)) {
- linker_error_printf(prog, "initializers for uniform "
- "`%s' have differing values\n",
- var->name);
- return false;
- }
- } else
- /* If the first-seen instance of a particular uniform did not
- * have an initializer but a later instance does, copy the
- * initializer to the version stored in the symbol table.
- */
- existing->constant_value =
- (ir_constant *)var->constant_value->clone(NULL);
- }
- } else
- uniforms.add_variable(var->name, var);
- }
- }
-
- return true;
-}
-
-
-/**
- * Validate that outputs from one stage match inputs of another
- */
-bool
-cross_validate_outputs_to_inputs(struct glsl_program *prog,
- glsl_shader *producer, glsl_shader *consumer)
-{
- glsl_symbol_table parameters;
- /* FINISHME: Figure these out dynamically. */
- const char *const producer_stage = "vertex";
- const char *const consumer_stage = "fragment";
-
- /* Find all shader outputs in the "producer" stage.
- */
- foreach_list(node, &producer->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
- /* FINISHME: For geometry shaders, this should also look for inout
- * FINISHME: variables.
- */
- if ((var == NULL) || (var->mode != ir_var_out))
- continue;
-
- parameters.add_variable(var->name, var);
- }
-
-
- /* Find all shader inputs in the "consumer" stage. Any variables that have
- * matching outputs already in the symbol table must have the same type and
- * qualifiers.
- */
- foreach_list(node, &consumer->ir) {
- ir_variable *const input = ((ir_instruction *) node)->as_variable();
-
- /* FINISHME: For geometry shaders, this should also look for inout
- * FINISHME: variables.
- */
- if ((input == NULL) || (input->mode != ir_var_in))
- continue;
-
- ir_variable *const output = parameters.get_variable(input->name);
- if (output != NULL) {
- /* Check that the types match between stages.
- */
- if (input->type != output->type) {
- linker_error_printf(prog,
- "%s shader output `%s' delcared as "
- "type `%s', but %s shader input declared "
- "as type `%s'\n",
- producer_stage, output->name,
- output->type->name,
- consumer_stage, input->type->name);
- return false;
- }
-
- /* Check that all of the qualifiers match between stages.
- */
- if (input->centroid != output->centroid) {
- linker_error_printf(prog,
- "%s shader output `%s' %s centroid qualifier, "
- "but %s shader input %s centroid qualifier\n",
- producer_stage,
- output->name,
- (output->centroid) ? "has" : "lacks",
- consumer_stage,
- (input->centroid) ? "has" : "lacks");
- return false;
- }
-
- if (input->invariant != output->invariant) {
- linker_error_printf(prog,
- "%s shader output `%s' %s invariant qualifier, "
- "but %s shader input %s invariant qualifier\n",
- producer_stage,
- output->name,
- (output->invariant) ? "has" : "lacks",
- consumer_stage,
- (input->invariant) ? "has" : "lacks");
- return false;
- }
-
- if (input->interpolation != output->interpolation) {
- linker_error_printf(prog,
- "%s shader output `%s' specifies %s "
- "interpolation qualifier, "
- "but %s shader input specifies %s "
- "interpolation qualifier\n",
- producer_stage,
- output->name,
- output->interpolation_string(),
- consumer_stage,
- input->interpolation_string());
- return false;
- }
- }
- }
-
- return true;
-}
-
-
-struct uniform_node {
- exec_node link;
- struct gl_uniform *u;
- unsigned slots;
-};
-
-void
-assign_uniform_locations(struct glsl_program *prog)
-{
- /* */
- exec_list uniforms;
- unsigned total_uniforms = 0;
- hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
- hash_table_string_compare);
-
- for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
- unsigned next_position = 0;
-
- foreach_list(node, &prog->_LinkedShaders[i]->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
- if ((var == NULL) || (var->mode != ir_var_uniform))
- continue;
-
- const unsigned vec4_slots = (var->component_slots() + 3) / 4;
- assert(vec4_slots != 0);
-
- uniform_node *n = (uniform_node *) hash_table_find(ht, var->name);
- if (n == NULL) {
- n = (uniform_node *) calloc(1, sizeof(struct uniform_node));
- n->u = (gl_uniform *) calloc(vec4_slots, sizeof(struct gl_uniform));
- n->slots = vec4_slots;
-
- n->u[0].Name = strdup(var->name);
- for (unsigned j = 1; j < vec4_slots; j++)
- n->u[j].Name = n->u[0].Name;
-
- hash_table_insert(ht, n, n->u[0].Name);
- uniforms.push_tail(& n->link);
- total_uniforms += vec4_slots;
- }
-
- if (var->constant_value != NULL)
- for (unsigned j = 0; j < vec4_slots; j++)
- n->u[j].Initialized = true;
-
- var->location = next_position;
-
- for (unsigned j = 0; j < vec4_slots; j++) {
- switch (prog->_LinkedShaders[i]->Type) {
- case GL_VERTEX_SHADER:
- n->u[j].VertPos = next_position;
- break;
- case GL_FRAGMENT_SHADER:
- n->u[j].FragPos = next_position;
- break;
- case GL_GEOMETRY_SHADER:
- /* FINISHME: Support geometry shaders. */
- assert(prog->_LinkedShaders[i]->Type != GL_GEOMETRY_SHADER);
- break;
- }
-
- next_position++;
- }
- }
- }
-
- gl_uniform_list *ul = (gl_uniform_list *)
- calloc(1, sizeof(gl_uniform_list));
-
- ul->Size = total_uniforms;
- ul->NumUniforms = total_uniforms;
- ul->Uniforms = (gl_uniform *) calloc(total_uniforms, sizeof(gl_uniform));
-
- unsigned idx = 0;
- uniform_node *next;
- for (uniform_node *node = (uniform_node *) uniforms.head
- ; node->link.next != NULL
- ; node = next) {
- next = (uniform_node *) node->link.next;
-
- node->link.remove();
- memcpy(&ul->Uniforms[idx], node->u, sizeof(gl_uniform) * node->slots);
- idx += node->slots;
-
- free(node->u);
- free(node);
- }
-
- hash_table_dtor(ht);
-
- prog->Uniforms = ul;
-}
-
-
-/**
- * Find a contiguous set of available bits in a bitmask
- *
- * \param used_mask Bits representing used (1) and unused (0) locations
- * \param needed_count Number of contiguous bits needed.
- *
- * \return
- * Base location of the available bits on success or -1 on failure.
- */
-int
-find_available_slots(unsigned used_mask, unsigned needed_count)
-{
- unsigned needed_mask = (1 << needed_count) - 1;
- const int max_bit_to_test = (8 * sizeof(used_mask)) - needed_count;
-
- /* The comparison to 32 is redundant, but without it GCC emits "warning:
- * cannot optimize possibly infinite loops" for the loop below.
- */
- if ((needed_count == 0) || (max_bit_to_test < 0) || (max_bit_to_test > 32))
- return -1;
-
- for (int i = 0; i <= max_bit_to_test; i++) {
- if ((needed_mask & ~used_mask) == needed_mask)
- return i;
-
- needed_mask <<= 1;
- }
-
- return -1;
-}
-
-
-bool
-assign_attribute_locations(glsl_program *prog, unsigned max_attribute_index)
-{
- /* Mark invalid attribute locations as being used.
- */
- unsigned used_locations = (max_attribute_index >= 32)
- ? ~0 : ~((1 << max_attribute_index) - 1);
-
- glsl_shader *const sh = prog->_LinkedShaders[0];
- assert(sh->Type == GL_VERTEX_SHADER);
-
- /* Operate in a total of four passes.
- *
- * 1. Invalidate the location assignments for all vertex shader inputs.
- *
- * 2. Assign locations for inputs that have user-defined (via
- * glBindVertexAttribLocation) locatoins.
- *
- * 3. Sort the attributes without assigned locations by number of slots
- * required in decreasing order. Fragmentation caused by attribute
- * locations assigned by the application may prevent large attributes
- * from having enough contiguous space.
- *
- * 4. Assign locations to any inputs without assigned locations.
- */
-
- invalidate_variable_locations(sh, ir_var_in, VERT_ATTRIB_GENERIC0);
-
- if (prog->Attributes != NULL) {
- for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) {
- ir_variable *const var =
- sh->symbols->get_variable(prog->Attributes->Parameters[i].Name);
-
- /* Note: attributes that occupy multiple slots, such as arrays or
- * matrices, may appear in the attrib array multiple times.
- */
- if ((var == NULL) || (var->location != -1))
- continue;
-
- /* From page 61 of the OpenGL 4.0 spec:
- *
- * "LinkProgram will fail if the attribute bindings assigned by
- * BindAttribLocation do not leave not enough space to assign a
- * location for an active matrix attribute or an active attribute
- * array, both of which require multiple contiguous generic
- * attributes."
- *
- * Previous versions of the spec contain similar language but omit the
- * bit about attribute arrays.
- *
- * Page 61 of the OpenGL 4.0 spec also says:
- *
- * "It is possible for an application to bind more than one
- * attribute name to the same location. This is referred to as
- * aliasing. This will only work if only one of the aliased
- * attributes is active in the executable program, or if no path
- * through the shader consumes more than one attribute of a set
- * of attributes aliased to the same location. A link error can
- * occur if the linker determines that every path through the
- * shader consumes multiple aliased attributes, but
- * implementations are not required to generate an error in this
- * case."
- *
- * These two paragraphs are either somewhat contradictory, or I don't
- * fully understand one or both of them.
- */
- /* FINISHME: The code as currently written does not support attribute
- * FINISHME: location aliasing (see comment above).
- */
- const int attr = prog->Attributes->Parameters[i].StateIndexes[0];
- const unsigned slots = count_attribute_slots(var->type);
-
- /* Mask representing the contiguous slots that will be used by this
- * attribute.
- */
- const unsigned use_mask = (1 << slots) - 1;
-
- /* Generate a link error if the set of bits requested for this
- * attribute overlaps any previously allocated bits.
- */
- if ((~(use_mask << attr) & used_locations) != used_locations) {
- linker_error_printf(prog,
- "insufficient contiguous attribute locations "
- "available for vertex shader input `%s'",
- var->name);
- return false;
- }
-
- var->location = VERT_ATTRIB_GENERIC0 + attr;
- used_locations |= (use_mask << attr);
- }
- }
-
- /* Temporary storage for the set of attributes that need locations assigned.
- */
- struct temp_attr {
- unsigned slots;
- ir_variable *var;
-
- /* Used below in the call to qsort. */
- static int compare(const void *a, const void *b)
- {
- const temp_attr *const l = (const temp_attr *) a;
- const temp_attr *const r = (const temp_attr *) b;
-
- /* Reversed because we want a descending order sort below. */
- return r->slots - l->slots;
- }
- } to_assign[16];
-
- unsigned num_attr = 0;
-
- foreach_list(node, &sh->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
- if ((var == NULL) || (var->mode != ir_var_in))
- continue;
-
- /* The location was explicitly assigned, nothing to do here.
- */
- if (var->location != -1)
- continue;
-
- to_assign[num_attr].slots = count_attribute_slots(var->type);
- to_assign[num_attr].var = var;
- num_attr++;
- }
-
- /* If all of the attributes were assigned locations by the application (or
- * are built-in attributes with fixed locations), return early. This should
- * be the common case.
- */
- if (num_attr == 0)
- return true;
-
- qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare);
-
- for (unsigned i = 0; i < num_attr; i++) {
- /* Mask representing the contiguous slots that will be used by this
- * attribute.
- */
- const unsigned use_mask = (1 << to_assign[i].slots) - 1;
-
- int location = find_available_slots(used_locations, to_assign[i].slots);
-
- if (location < 0) {
- linker_error_printf(prog,
- "insufficient contiguous attribute locations "
- "available for vertex shader input `%s'",
- to_assign[i].var->name);
- return false;
- }
-
- to_assign[i].var->location = VERT_ATTRIB_GENERIC0 + location;
- used_locations |= (use_mask << location);
- }
-
- return true;
-}
-
-
-void
-assign_varying_locations(glsl_shader *producer, glsl_shader *consumer)
-{
- /* FINISHME: Set dynamically when geometry shader support is added. */
- unsigned output_index = VERT_RESULT_VAR0;
- unsigned input_index = FRAG_ATTRIB_VAR0;
-
- /* Operate in a total of three passes.
- *
- * 1. Assign locations for any matching inputs and outputs.
- *
- * 2. Mark output variables in the producer that do not have locations as
- * not being outputs. This lets the optimizer eliminate them.
- *
- * 3. Mark input variables in the consumer that do not have locations as
- * not being inputs. This lets the optimizer eliminate them.
- */
-
- invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_VAR0);
- invalidate_variable_locations(consumer, ir_var_in, FRAG_ATTRIB_VAR0);
-
- foreach_list(node, &producer->ir) {
- ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
-
- if ((output_var == NULL) || (output_var->mode != ir_var_out)
- || (output_var->location != -1))
- continue;
-
- ir_variable *const input_var =
- consumer->symbols->get_variable(output_var->name);
-
- if ((input_var == NULL) || (input_var->mode != ir_var_in))
- continue;
-
- assert(input_var->location == -1);
-
- /* FINISHME: Location assignment will need some changes when arrays,
- * FINISHME: matrices, and structures are allowed as shader inputs /
- * FINISHME: outputs.
- */
- output_var->location = output_index;
- input_var->location = input_index;
-
- output_index++;
- input_index++;
- }
-
- foreach_list(node, &producer->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
- if ((var == NULL) || (var->mode != ir_var_out))
- continue;
-
- /* An 'out' variable is only really a shader output if its value is read
- * by the following stage.
- */
- var->shader_out = (var->location != -1);
- }
-
- foreach_list(node, &consumer->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
- if ((var == NULL) || (var->mode != ir_var_in))
- continue;
-
- /* An 'in' variable is only really a shader input if its value is written
- * by the previous stage.
- */
- var->shader_in = (var->location != -1);
- }
-}
-
-
-void
-link_shaders(struct glsl_program *prog)
-{
- prog->LinkStatus = false;
- prog->Validated = false;
- prog->_Used = false;
-
- if (prog->InfoLog != NULL)
- talloc_free(prog->InfoLog);
-
- prog->InfoLog = talloc_strdup(NULL, "");
-
- /* Separate the shaders into groups based on their type.
- */
- struct glsl_shader **vert_shader_list;
- unsigned num_vert_shaders = 0;
- struct glsl_shader **frag_shader_list;
- unsigned num_frag_shaders = 0;
-
- vert_shader_list = (struct glsl_shader **)
- calloc(2 * prog->NumShaders, sizeof(struct glsl_shader *));
- frag_shader_list = &vert_shader_list[prog->NumShaders];
-
- for (unsigned i = 0; i < prog->NumShaders; i++) {
- switch (prog->Shaders[i]->Type) {
- case GL_VERTEX_SHADER:
- vert_shader_list[num_vert_shaders] = prog->Shaders[i];
- num_vert_shaders++;
- break;
- case GL_FRAGMENT_SHADER:
- frag_shader_list[num_frag_shaders] = prog->Shaders[i];
- num_frag_shaders++;
- break;
- case GL_GEOMETRY_SHADER:
- /* FINISHME: Support geometry shaders. */
- assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER);
- break;
- }
- }
-
- /* FINISHME: Implement intra-stage linking. */
- assert(num_vert_shaders <= 1);
- assert(num_frag_shaders <= 1);
-
- /* Verify that each of the per-target executables is valid.
- */
- if (!validate_vertex_shader_executable(prog, vert_shader_list[0])
- || !validate_fragment_shader_executable(prog, frag_shader_list[0]))
- goto done;
-
-
- prog->_LinkedShaders = (struct glsl_shader **)
- calloc(2, sizeof(struct glsl_shader *));
- prog->_NumLinkedShaders = 0;
-
- if (num_vert_shaders > 0) {
- prog->_LinkedShaders[prog->_NumLinkedShaders] = vert_shader_list[0];
- prog->_NumLinkedShaders++;
- }
-
- if (num_frag_shaders > 0) {
- prog->_LinkedShaders[prog->_NumLinkedShaders] = frag_shader_list[0];
- prog->_NumLinkedShaders++;
- }
-
- /* Here begins the inter-stage linking phase. Some initial validation is
- * performed, then locations are assigned for uniforms, attributes, and
- * varyings.
- */
- if (cross_validate_uniforms(prog)) {
- /* Validate the inputs of each stage with the output of the preceeding
- * stage.
- */
- for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) {
- if (!cross_validate_outputs_to_inputs(prog,
- prog->_LinkedShaders[i - 1],
- prog->_LinkedShaders[i]))
- goto done;
- }
-
- prog->LinkStatus = true;
- }
-
- /* FINISHME: Perform whole-program optimization here. */
-
- assign_uniform_locations(prog);
-
- if (prog->_LinkedShaders[0]->Type == GL_VERTEX_SHADER)
- /* FINISHME: The value of the max_attribute_index parameter is
- * FINISHME: implementation dependent based on the value of
- * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
- * FINISHME: at least 16, so hardcode 16 for now.
- */
- if (!assign_attribute_locations(prog, 16))
- goto done;
-
- for (unsigned i = 1; i < prog->_NumLinkedShaders; i++)
- assign_varying_locations(prog->_LinkedShaders[i - 1],
- prog->_LinkedShaders[i]);
-
- /* FINISHME: Assign fragment shader output locations. */
-
-done:
- free(vert_shader_list);
-}
+++ /dev/null
-/*
- * Copyright © 2008, 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.
- */
-
-/**
- * \file list.h
- * \brief Doubly-linked list abstract container type.
- *
- * Each doubly-linked list has a sentinal head and tail node. These nodes
- * contain no data. The head sentinal can be identified by its \c prev
- * pointer being \c NULL. The tail sentinal can be identified by its
- * \c next pointer being \c NULL.
- *
- * A list is empty if either the head sentinal's \c next pointer points to the
- * tail sentinal or the tail sentinal's \c prev poiner points to the head
- * sentinal.
- *
- * Instead of tracking two separate \c node structures and a \c list structure
- * that points to them, the sentinal nodes are in a single structure. Noting
- * that each sentinal node always has one \c NULL pointer, the \c NULL
- * pointers occupy the same memory location. In the \c list structure
- * contains a the following:
- *
- * - A \c head pointer that represents the \c next pointer of the
- * head sentinal node.
- * - A \c tail pointer that represents the \c prev pointer of the head
- * sentinal node and the \c next pointer of the tail sentinal node. This
- * pointer is \b always \c NULL.
- * - A \c tail_prev pointer that represents the \c prev pointer of the
- * tail sentinal node.
- *
- * Therefore, if \c head->next is \c NULL or \c tail_prev->prev is \c NULL,
- * the list is empty.
- *
- * To anyone familiar with "exec lists" on the Amiga, this structure should
- * be immediately recognizable. See the following link for the original Amiga
- * operating system documentation on the subject.
- *
- * http://www.natami.net/dev/Libraries_Manual_guide/node02D7.html
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#pragma once
-#ifndef LIST_CONTAINER_H
-#define LIST_CONTAINER_H
-
-#ifndef __cplusplus
-#include <stddef.h>
-#include <talloc.h>
-#else
-extern "C" {
-#include <talloc.h>
-}
-#endif
-
-#include <assert.h>
-
-struct exec_node {
- struct exec_node *next;
- struct exec_node *prev;
-
-#ifdef __cplusplus
- /* 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_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 *node)
- {
- talloc_free(node);
- }
-
- exec_node() : next(NULL), prev(NULL)
- {
- /* empty */
- }
-
- const exec_node *get_next() const
- {
- return next;
- }
-
- exec_node *get_next()
- {
- return next;
- }
-
- const exec_node *get_prev() const
- {
- return prev;
- }
-
- exec_node *get_prev()
- {
- return prev;
- }
-
- void remove()
- {
- next->prev = prev;
- prev->next = next;
- next = NULL;
- prev = NULL;
- }
-
- /**
- * Link a node with itself
- *
- * This creates a sort of degenerate list that is occasionally useful.
- */
- void self_link()
- {
- next = this;
- prev = this;
- }
-
- /**
- * Insert a node in the list after the current node
- */
- void insert_after(exec_node *after)
- {
- after->next = this->next;
- after->prev = this;
-
- this->next->prev = after;
- this->next = after;
- }
- /**
- * Insert a node in the list before the current node
- */
- void insert_before(exec_node *before)
- {
- before->next = this;
- before->prev = this->prev;
-
- this->prev->next = before;
- this->prev = before;
- }
-
- /**
- * Is this the sentinal at the tail of the list?
- */
- bool is_tail_sentinal() const
- {
- return this->next == NULL;
- }
-
- /**
- * Is this the sentinal at the head of the list?
- */
- bool is_head_sentinal() const
- {
- return this->prev == NULL;
- }
-#endif
-};
-
-
-#ifdef __cplusplus
-/* This macro will not work correctly if `t' uses virtual inheritance. If you
- * are using virtual inheritance, you deserve a slow and painful death. Enjoy!
- */
-#define exec_list_offsetof(t, f, p) \
- (((char *) &((t *) p)->f) - ((char *) p))
-#else
-#define exec_list_offsetof(t, f, p) offsetof(t, f)
-#endif
-
-/**
- * Get a pointer to the structure containing an exec_node
- *
- * Given a pointer to an \c exec_node embedded in a structure, get a pointer to
- * the containing structure.
- *
- * \param type Base type of the structure containing the node
- * \param node Pointer to the \c exec_node
- * \param field Name of the field in \c type that is the embedded \c exec_node
- */
-#define exec_node_data(type, node, field) \
- ((type *) (((char *) node) - exec_list_offsetof(type, field, node)))
-
-#ifdef __cplusplus
-struct exec_node;
-
-class iterator {
-public:
- void next()
- {
- }
-
- void *get()
- {
- return NULL;
- }
-
- bool has_next() const
- {
- return false;
- }
-};
-
-class exec_list_iterator : public iterator {
-public:
- exec_list_iterator(exec_node *n) : node(n), _next(n->next)
- {
- /* empty */
- }
-
- void next()
- {
- node = _next;
- _next = node->next;
- }
-
- void remove()
- {
- node->remove();
- }
-
- exec_node *get()
- {
- return node;
- }
-
- bool has_next() const
- {
- return _next != NULL;
- }
-
-private:
- exec_node *node;
- exec_node *_next;
-};
-
-#define foreach_iter(iter_type, iter, container) \
- for (iter_type iter = (container) . iterator(); iter.has_next(); iter.next())
-#endif
-
-
-struct exec_list {
- struct exec_node *head;
- struct exec_node *tail;
- struct exec_node *tail_pred;
-
-#ifdef __cplusplus
- exec_list()
- {
- make_empty();
- }
-
- void make_empty()
- {
- head = (exec_node *) & tail;
- tail = NULL;
- tail_pred = (exec_node *) & head;
- }
-
- bool is_empty() const
- {
- /* There are three ways to test whether a list is empty or not.
- *
- * - Check to see if the \c head points to the \c tail.
- * - Check to see if the \c tail_pred points to the \c head.
- * - Check to see if the \c head is the sentinal node by test whether its
- * \c next pointer is \c NULL.
- *
- * The first two methods tend to generate better code on modern systems
- * because they save a pointer dereference.
- */
- return head == (exec_node *) &tail;
- }
-
- const exec_node *get_head() const
- {
- return !is_empty() ? head : NULL;
- }
-
- exec_node *get_head()
- {
- return !is_empty() ? head : NULL;
- }
-
- const exec_node *get_tail() const
- {
- return !is_empty() ? tail_pred : NULL;
- }
-
- exec_node *get_tail()
- {
- return !is_empty() ? tail_pred : NULL;
- }
-
- void push_head(exec_node *n)
- {
- n->next = head;
- n->prev = (exec_node *) &head;
-
- n->next->prev = n;
- head = n;
- }
-
- void push_tail(exec_node *n)
- {
- n->next = (exec_node *) &tail;
- n->prev = tail_pred;
-
- n->prev->next = n;
- tail_pred = n;
- }
-
- void push_degenerate_list_at_head(exec_node *n)
- {
- assert(n->prev->next == n);
-
- n->prev->next = head;
- head->prev = n->prev;
- n->prev = (exec_node *) &head;
- head = n;
- }
-
- /**
- * Move all of the nodes from this list to the target list
- */
- void move_nodes_to(exec_list *target)
- {
- if (is_empty()) {
- target->make_empty();
- } else {
- target->head = head;
- target->tail = NULL;
- target->tail_pred = tail_pred;
-
- target->head->prev = (exec_node *) &target->head;
- target->tail_pred->next = (exec_node *) &target->tail;
-
- make_empty();
- }
- }
-
- exec_list_iterator iterator()
- {
- return exec_list_iterator(head);
- }
-
- exec_list_iterator iterator() const
- {
- return exec_list_iterator((exec_node *) head);
- }
-#endif
-};
-
-#define foreach_list(__node, __list) \
- for (exec_node * __node = (__list)->head \
- ; (__node)->next != NULL \
- ; (__node) = (__node)->next)
-
-#define foreach_list_const(__node, __list) \
- for (const exec_node * __node = (__list)->head \
- ; (__node)->next != NULL \
- ; (__node) = (__node)->next)
-
-#define foreach_list_typed(__type, __node, __field, __list) \
- for (__type * __node = \
- exec_node_data(__type, (__list)->head, __field); \
- (__node)->__field.next != NULL; \
- (__node) = exec_node_data(__type, (__node)->__field.next, __field))
-
-#define foreach_list_typed_const(__type, __node, __field, __list) \
- for (const __type * __node = \
- exec_node_data(__type, (__list)->head, __field); \
- (__node)->__field.next != NULL; \
- (__node) = exec_node_data(__type, (__node)->__field.next, __field))
-
-#endif /* LIST_CONTAINER_H */
+++ /dev/null
-/*
- * 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 <cstdlib>
-#include <cstdio>
-#include <getopt.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "ast.h"
-#include "glsl_parser_extras.h"
-#include "glsl_parser.h"
-#include "ir_optimization.h"
-#include "ir_print_visitor.h"
-#include "program.h"
-
-/* Returned string will have 'ctx' as its talloc owner. */
-static char *
-load_text_file(void *ctx, const char *file_name, size_t *size)
-{
- char *text = NULL;
- struct stat st;
- ssize_t total_read = 0;
- int fd = open(file_name, O_RDONLY);
-
- *size = 0;
- if (fd < 0) {
- return NULL;
- }
-
- if (fstat(fd, & st) == 0) {
- text = (char *) talloc_size(ctx, st.st_size + 1);
- if (text != NULL) {
- do {
- ssize_t bytes = read(fd, text + total_read,
- st.st_size - total_read);
- if (bytes < 0) {
- free(text);
- text = NULL;
- break;
- }
-
- if (bytes == 0) {
- break;
- }
-
- total_read += bytes;
- } while (total_read < st.st_size);
-
- text[total_read] = '\0';
- *size = total_read;
- }
- }
-
- close(fd);
-
- return text;
-}
-
-
-void
-usage_fail(const char *name)
-{
- printf("%s <filename.frag|filename.vert>\n", name);
- exit(EXIT_FAILURE);
-}
-
-
-int dump_ast = 0;
-int dump_lir = 0;
-int do_link = 0;
-
-const struct option compiler_opts[] = {
- { "dump-ast", 0, &dump_ast, 1 },
- { "dump-lir", 0, &dump_lir, 1 },
- { "link", 0, &do_link, 1 },
- { NULL, 0, NULL, 0 }
-};
-
-void
-compile_shader(struct glsl_shader *shader)
-{
- struct _mesa_glsl_parse_state *state;
-
- state = talloc_zero(talloc_parent(shader), struct _mesa_glsl_parse_state);
-
- switch (shader->Type) {
- case GL_VERTEX_SHADER: state->target = vertex_shader; break;
- case GL_FRAGMENT_SHADER: state->target = fragment_shader; break;
- case GL_GEOMETRY_SHADER: state->target = geometry_shader; break;
- }
-
- state->scanner = NULL;
- state->translation_unit.make_empty();
- state->symbols = new(shader) glsl_symbol_table;
- state->info_log = talloc_strdup(shader, "");
- state->error = false;
- state->temp_index = 0;
- state->loop_or_switch_nesting = NULL;
- state->ARB_texture_rectangle_enable = true;
-
- /* Create a new context for the preprocessor output. Ultimately, this
- * should probably be the parser context, but there isn't one yet.
- */
- const char *source = shader->Source;
- state->error = preprocess(shader, &source, &state->info_log);
-
- if (!state->error) {
- _mesa_glsl_lexer_ctor(state, source);
- _mesa_glsl_parse(state);
- _mesa_glsl_lexer_dtor(state);
- }
-
- if (dump_ast) {
- foreach_list_const(n, &state->translation_unit) {
- ast_node *ast = exec_node_data(ast_node, n, link);
- ast->print();
- }
- printf("\n\n");
- }
-
- shader->ir.make_empty();
- if (!state->error && !state->translation_unit.is_empty())
- _mesa_ast_to_hir(&shader->ir, state);
-
- validate_ir_tree(&shader->ir);
-
- /* Optimization passes */
- if (!state->error && !shader->ir.is_empty()) {
- bool progress;
- do {
- progress = false;
-
- progress = do_function_inlining(&shader->ir) || progress;
- progress = do_if_simplification(&shader->ir) || progress;
- progress = do_copy_propagation(&shader->ir) || progress;
- progress = do_dead_code_local(&shader->ir) || progress;
- progress = do_dead_code_unlinked(&shader->ir) || progress;
- progress = do_constant_variable_unlinked(&shader->ir) || progress;
- progress = do_constant_folding(&shader->ir) || progress;
- progress = do_vec_index_to_swizzle(&shader->ir) || progress;
- progress = do_swizzle_swizzle(&shader->ir) || progress;
- } while (progress);
- }
-
- validate_ir_tree(&shader->ir);
-
- /* Print out the resulting IR */
- if (!state->error && dump_lir) {
- _mesa_print_ir(&shader->ir, state);
- }
-
- shader->symbols = state->symbols;
- shader->CompileStatus = !state->error;
-
- if (shader->InfoLog)
- talloc_free(shader->InfoLog);
-
- shader->InfoLog = state->info_log;
-
- talloc_free(state);
-
- return;
-}
-
-int
-main(int argc, char **argv)
-{
- int status = EXIT_SUCCESS;
-
- int c;
- int idx = 0;
- while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1)
- /* empty */ ;
-
-
- if (argc <= optind)
- usage_fail(argv[0]);
-
- struct glsl_program *whole_program;
-
- whole_program = talloc_zero (NULL, struct glsl_program);
- assert(whole_program != NULL);
-
- for (/* empty */; argc > optind; optind++) {
- whole_program->Shaders = (struct glsl_shader **)
- talloc_realloc(whole_program, whole_program->Shaders,
- struct glsl_shader *, whole_program->NumShaders + 1);
- assert(whole_program->Shaders != NULL);
-
- struct glsl_shader *shader = talloc_zero(whole_program, glsl_shader);
-
- whole_program->Shaders[whole_program->NumShaders] = shader;
- whole_program->NumShaders++;
-
- const unsigned len = strlen(argv[optind]);
- if (len < 6)
- usage_fail(argv[0]);
-
- const char *const ext = & argv[optind][len - 5];
- if (strncmp(".vert", ext, 5) == 0)
- shader->Type = GL_VERTEX_SHADER;
- else if (strncmp(".geom", ext, 5) == 0)
- shader->Type = GL_GEOMETRY_SHADER;
- else if (strncmp(".frag", ext, 5) == 0)
- shader->Type = GL_FRAGMENT_SHADER;
- else
- usage_fail(argv[0]);
-
- shader->Source = load_text_file(whole_program,
- argv[optind], &shader->SourceLen);
- if (shader->Source == NULL) {
- printf("File \"%s\" does not exist.\n", argv[optind]);
- exit(EXIT_FAILURE);
- }
-
- compile_shader(shader);
-
- if (!shader->CompileStatus) {
- printf("Info log for %s:\n%s\n", argv[optind], shader->InfoLog);
- status = EXIT_FAILURE;
- break;
- }
- }
-
- if ((status == EXIT_SUCCESS) && do_link) {
- link_shaders(whole_program);
- status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
- }
-
- talloc_free(whole_program);
-
- return status;
-}
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#define _mesa_malloc(x) malloc(x)
-#define _mesa_free(x) free(x)
-#define _mesa_calloc(x) calloc(1,x)
+++ /dev/null
-/*
- * 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
-
-#define MAX_DRAW_BUFFERS 8
-#define MAX_VARYING 16
-
-#include <GL/gl.h>
-
-/**
- * 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 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_COLOR = 1,
- FRAG_RESULT_DATA0 = 2,
- FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
-} gl_frag_result;
-
-/**
- * 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_UNDEFINED, /**< Invalid/TBD value */
- PROGRAM_FILE_MAX
-} gl_register_file;
-
-/**
- * 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;
-
-#endif /* MTYPES_H */
+++ /dev/null
-/**
- * \file simple_list.h
- * Simple macros for type-safe, intrusive lists.
- *
- * Intended to work with a list sentinal which is created as an empty
- * list. Insert & delete are O(1).
- *
- * \author
- * (C) 1997, Keith Whitwell
- */
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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.
- */
-
-
-#ifndef _SIMPLE_LIST_H
-#define _SIMPLE_LIST_H
-
-struct simple_node {
- struct simple_node *next;
- struct simple_node *prev;
-};
-
-/**
- * Remove an element from list.
- *
- * \param elem element to remove.
- */
-#define remove_from_list(elem) \
-do { \
- (elem)->next->prev = (elem)->prev; \
- (elem)->prev->next = (elem)->next; \
-} while (0)
-
-/**
- * Insert an element to the list head.
- *
- * \param list list.
- * \param elem element to insert.
- */
-#define insert_at_head(list, elem) \
-do { \
- (elem)->prev = list; \
- (elem)->next = (list)->next; \
- (list)->next->prev = elem; \
- (list)->next = elem; \
-} while(0)
-
-/**
- * Insert an element to the list tail.
- *
- * \param list list.
- * \param elem element to insert.
- */
-#define insert_at_tail(list, elem) \
-do { \
- (elem)->next = list; \
- (elem)->prev = (list)->prev; \
- (list)->prev->next = elem; \
- (list)->prev = elem; \
-} while(0)
-
-/**
- * Move an element to the list head.
- *
- * \param list list.
- * \param elem element to move.
- */
-#define move_to_head(list, elem) \
-do { \
- remove_from_list(elem); \
- insert_at_head(list, elem); \
-} while (0)
-
-/**
- * Move an element to the list tail.
- *
- * \param list list.
- * \param elem element to move.
- */
-#define move_to_tail(list, elem) \
-do { \
- remove_from_list(elem); \
- insert_at_tail(list, elem); \
-} while (0)
-
-/**
- * Consatinate a cyclic list to a list
- *
- * Appends the sequence of nodes starting with \c tail to the list \c head.
- * A "cyclic list" is a list that does not have a sentinal node. This means
- * that the data pointed to by \c tail is an actual node, not a dataless
- * sentinal. Note that if \c tail constist of a single node, this macro
- * behaves identically to \c insert_at_tail
- *
- * \param head Head of the list to be appended to. This may or may not
- * be a cyclic list.
- * \param tail Head of the cyclic list to be appended to \c head.
- * \param temp Temporary \c simple_list used by the macro
- *
- * \sa insert_at_tail
- */
-#define concat_list_and_cycle(head, tail, temp) \
-do { \
- (head)->prev->next = (tail); \
- (tail)->prev->next = (head); \
- (temp) = (head)->prev; \
- (head)->prev = (tail)->prev; \
- (tail)->prev = (temp); \
-} while (0)
-
-#define concat_list(head, next_list) \
-do { \
- (next_list)->next->prev = (head)->prev; \
- (next_list)->prev->next = (head); \
- (head)->prev->next = (next_list)->next; \
- (head)->prev = (next_list)->prev; \
-} while (0)
-
-/**
- * Make a empty list empty.
- *
- * \param sentinal list (sentinal element).
- */
-#define make_empty_list(sentinal) \
-do { \
- (sentinal)->next = sentinal; \
- (sentinal)->prev = sentinal; \
-} while (0)
-
-/**
- * Get list first element.
- *
- * \param list list.
- *
- * \return pointer to first element.
- */
-#define first_elem(list) ((list)->next)
-
-/**
- * Get list last element.
- *
- * \param list list.
- *
- * \return pointer to last element.
- */
-#define last_elem(list) ((list)->prev)
-
-/**
- * Get next element.
- *
- * \param elem element.
- *
- * \return pointer to next element.
- */
-#define next_elem(elem) ((elem)->next)
-
-/**
- * Get previous element.
- *
- * \param elem element.
- *
- * \return pointer to previous element.
- */
-#define prev_elem(elem) ((elem)->prev)
-
-/**
- * Test whether element is at end of the list.
- *
- * \param list list.
- * \param elem element.
- *
- * \return non-zero if element is at end of list, or zero otherwise.
- */
-#define at_end(list, elem) ((elem) == (list))
-
-/**
- * Test if a list is empty.
- *
- * \param list list.
- *
- * \return non-zero if list empty, or zero otherwise.
- */
-#define is_empty_list(list) ((list)->next == (list))
-
-/**
- * Walk through the elements of a list.
- *
- * \param ptr pointer to the current element.
- * \param list list.
- *
- * \note It should be followed by a { } block or a single statement, as in a \c
- * for loop.
- */
-#define foreach(ptr, list) \
- for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next )
-
-/**
- * Walk through the elements of a list.
- *
- * Same as #foreach but lets you unlink the current value during a list
- * traversal. Useful for freeing a list, element by element.
- *
- * \param ptr pointer to the current element.
- * \param t temporary pointer.
- * \param list list.
- *
- * \note It should be followed by a { } block or a single statement, as in a \c
- * for loop.
- */
-#define foreach_s(ptr, t, list) \
- for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
-
-#endif
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 1999-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.
- */
-
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#if 0
-#include "main/glheader.h"
-#else
-#define _mesa_strdup strdup
-#define _mesa_snprintf snprintf
-#define ASSERT assert
-#endif
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "prog_instruction.h"
-
-
-/**
- * Initialize program instruction fields to defaults.
- * \param inst first instruction to initialize
- * \param count number of instructions to initialize
- */
-void
-_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
-{
- GLuint i;
-
- memset(inst, 0, count * sizeof(struct prog_instruction));
-
- for (i = 0; i < count; i++) {
- inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
- inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
- inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
- inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
- inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
- inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
-
- inst[i].DstReg.File = PROGRAM_UNDEFINED;
- inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
- inst[i].DstReg.CondMask = COND_TR;
- inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
-
- inst[i].SaturateMode = SATURATE_OFF;
- inst[i].Precision = FLOAT32;
- }
-}
-
-
-/**
- * Allocate an array of program instructions.
- * \param numInst number of instructions
- * \return pointer to instruction memory
- */
-struct prog_instruction *
-_mesa_alloc_instructions(GLuint numInst)
-{
- return (struct prog_instruction *)
- calloc(1, numInst * sizeof(struct prog_instruction));
-}
-
-
-/**
- * Reallocate memory storing an array of program instructions.
- * This is used when we need to append additional instructions onto an
- * program.
- * \param oldInst pointer to first of old/src instructions
- * \param numOldInst number of instructions at <oldInst>
- * \param numNewInst desired size of new instruction array.
- * \return pointer to start of new instruction array.
- */
-struct prog_instruction *
-_mesa_realloc_instructions(struct prog_instruction *oldInst,
- GLuint numOldInst, GLuint numNewInst)
-{
- struct prog_instruction *newInst;
-
- (void)numOldInst;
- newInst = (struct prog_instruction *)
- realloc(oldInst,
- numNewInst * sizeof(struct prog_instruction));
-
- return newInst;
-}
-
-
-/**
- * Copy an array of program instructions.
- * \param dest pointer to destination.
- * \param src pointer to source.
- * \param n number of instructions to copy.
- * \return pointer to destination.
- */
-struct prog_instruction *
-_mesa_copy_instructions(struct prog_instruction *dest,
- const struct prog_instruction *src, GLuint n)
-{
- GLuint i;
- memcpy(dest, src, n * sizeof(struct prog_instruction));
- for (i = 0; i < n; i++) {
- if (src[i].Comment)
- dest[i].Comment = _mesa_strdup(src[i].Comment);
- }
- return dest;
-}
-
-
-/**
- * Free an array of instructions
- */
-void
-_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
-{
- GLuint i;
- for (i = 0; i < count; i++) {
- if (inst[i].Data)
- free(inst[i].Data);
- if (inst[i].Comment)
- free((char *) inst[i].Comment);
- }
- free(inst);
-}
-
-
-/**
- * Basic info about each instruction
- */
-struct instruction_info
-{
- gl_inst_opcode Opcode;
- const char *Name;
- GLuint NumSrcRegs;
- GLuint NumDstRegs;
-};
-
-/**
- * Instruction info
- * \note Opcode should equal array index!
- */
-static const struct instruction_info InstInfo[MAX_OPCODE] = {
- { OPCODE_NOP, "NOP", 0, 0 },
- { OPCODE_ABS, "ABS", 1, 1 },
- { OPCODE_ADD, "ADD", 2, 1 },
- { OPCODE_AND, "AND", 2, 1 },
- { OPCODE_ARA, "ARA", 1, 1 },
- { OPCODE_ARL, "ARL", 1, 1 },
- { OPCODE_ARL_NV, "ARL_NV", 1, 1 },
- { OPCODE_ARR, "ARL", 1, 1 },
- { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
- { OPCODE_BGNSUB, "BGNSUB", 0, 0 },
- { OPCODE_BRA, "BRA", 0, 0 },
- { OPCODE_BRK, "BRK", 0, 0 },
- { OPCODE_CAL, "CAL", 0, 0 },
- { OPCODE_CMP, "CMP", 3, 1 },
- { OPCODE_CONT, "CONT", 0, 0 },
- { OPCODE_COS, "COS", 1, 1 },
- { OPCODE_DDX, "DDX", 1, 1 },
- { OPCODE_DDY, "DDY", 1, 1 },
- { OPCODE_DP2, "DP2", 2, 1 },
- { OPCODE_DP2A, "DP2A", 3, 1 },
- { OPCODE_DP3, "DP3", 2, 1 },
- { OPCODE_DP4, "DP4", 2, 1 },
- { OPCODE_DPH, "DPH", 2, 1 },
- { OPCODE_DST, "DST", 2, 1 },
- { OPCODE_ELSE, "ELSE", 0, 0 },
- { OPCODE_END, "END", 0, 0 },
- { OPCODE_ENDIF, "ENDIF", 0, 0 },
- { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
- { OPCODE_ENDSUB, "ENDSUB", 0, 0 },
- { OPCODE_EX2, "EX2", 1, 1 },
- { OPCODE_EXP, "EXP", 1, 1 },
- { OPCODE_FLR, "FLR", 1, 1 },
- { OPCODE_FRC, "FRC", 1, 1 },
- { OPCODE_IF, "IF", 1, 0 },
- { OPCODE_KIL, "KIL", 1, 0 },
- { OPCODE_KIL_NV, "KIL_NV", 0, 0 },
- { OPCODE_LG2, "LG2", 1, 1 },
- { OPCODE_LIT, "LIT", 1, 1 },
- { OPCODE_LOG, "LOG", 1, 1 },
- { OPCODE_LRP, "LRP", 3, 1 },
- { OPCODE_MAD, "MAD", 3, 1 },
- { OPCODE_MAX, "MAX", 2, 1 },
- { OPCODE_MIN, "MIN", 2, 1 },
- { OPCODE_MOV, "MOV", 1, 1 },
- { OPCODE_MUL, "MUL", 2, 1 },
- { OPCODE_NOISE1, "NOISE1", 1, 1 },
- { OPCODE_NOISE2, "NOISE2", 1, 1 },
- { OPCODE_NOISE3, "NOISE3", 1, 1 },
- { OPCODE_NOISE4, "NOISE4", 1, 1 },
- { OPCODE_NOT, "NOT", 1, 1 },
- { OPCODE_NRM3, "NRM3", 1, 1 },
- { OPCODE_NRM4, "NRM4", 1, 1 },
- { OPCODE_OR, "OR", 2, 1 },
- { OPCODE_PK2H, "PK2H", 1, 1 },
- { OPCODE_PK2US, "PK2US", 1, 1 },
- { OPCODE_PK4B, "PK4B", 1, 1 },
- { OPCODE_PK4UB, "PK4UB", 1, 1 },
- { OPCODE_POW, "POW", 2, 1 },
- { OPCODE_POPA, "POPA", 0, 0 },
- { OPCODE_PRINT, "PRINT", 1, 0 },
- { OPCODE_PUSHA, "PUSHA", 0, 0 },
- { OPCODE_RCC, "RCC", 1, 1 },
- { OPCODE_RCP, "RCP", 1, 1 },
- { OPCODE_RET, "RET", 0, 0 },
- { OPCODE_RFL, "RFL", 1, 1 },
- { OPCODE_RSQ, "RSQ", 1, 1 },
- { OPCODE_SCS, "SCS", 1, 1 },
- { OPCODE_SEQ, "SEQ", 2, 1 },
- { OPCODE_SFL, "SFL", 0, 1 },
- { OPCODE_SGE, "SGE", 2, 1 },
- { OPCODE_SGT, "SGT", 2, 1 },
- { OPCODE_SIN, "SIN", 1, 1 },
- { OPCODE_SLE, "SLE", 2, 1 },
- { OPCODE_SLT, "SLT", 2, 1 },
- { OPCODE_SNE, "SNE", 2, 1 },
- { OPCODE_SSG, "SSG", 1, 1 },
- { OPCODE_STR, "STR", 0, 1 },
- { OPCODE_SUB, "SUB", 2, 1 },
- { OPCODE_SWZ, "SWZ", 1, 1 },
- { OPCODE_TEX, "TEX", 1, 1 },
- { OPCODE_TXB, "TXB", 1, 1 },
- { OPCODE_TXD, "TXD", 3, 1 },
- { OPCODE_TXL, "TXL", 1, 1 },
- { OPCODE_TXP, "TXP", 1, 1 },
- { OPCODE_TXP_NV, "TXP_NV", 1, 1 },
- { OPCODE_TRUNC, "TRUNC", 1, 1 },
- { OPCODE_UP2H, "UP2H", 1, 1 },
- { OPCODE_UP2US, "UP2US", 1, 1 },
- { OPCODE_UP4B, "UP4B", 1, 1 },
- { OPCODE_UP4UB, "UP4UB", 1, 1 },
- { OPCODE_X2D, "X2D", 3, 1 },
- { OPCODE_XOR, "XOR", 2, 1 },
- { OPCODE_XPD, "XPD", 2, 1 }
-};
-
-
-/**
- * Return the number of src registers for the given instruction/opcode.
- */
-GLuint
-_mesa_num_inst_src_regs(gl_inst_opcode opcode)
-{
- ASSERT(opcode < MAX_OPCODE);
- ASSERT(opcode == InstInfo[opcode].Opcode);
- ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
- return InstInfo[opcode].NumSrcRegs;
-}
-
-
-/**
- * Return the number of dst registers for the given instruction/opcode.
- */
-GLuint
-_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
-{
- ASSERT(opcode < MAX_OPCODE);
- ASSERT(opcode == InstInfo[opcode].Opcode);
- ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
- return InstInfo[opcode].NumDstRegs;
-}
-
-
-GLboolean
-_mesa_is_tex_instruction(gl_inst_opcode opcode)
-{
- return (opcode == OPCODE_TEX ||
- opcode == OPCODE_TXB ||
- opcode == OPCODE_TXD ||
- opcode == OPCODE_TXL ||
- opcode == OPCODE_TXP);
-}
-
-
-/**
- * Check if there's a potential src/dst register data dependency when
- * using SOA execution.
- * Example:
- * MOV T, T.yxwz;
- * This would expand into:
- * MOV t0, t1;
- * MOV t1, t0;
- * MOV t2, t3;
- * MOV t3, t2;
- * The second instruction will have the wrong value for t0 if executed as-is.
- */
-GLboolean
-_mesa_check_soa_dependencies(const struct prog_instruction *inst)
-{
- GLuint i, chan;
-
- if (inst->DstReg.WriteMask == WRITEMASK_X ||
- inst->DstReg.WriteMask == WRITEMASK_Y ||
- inst->DstReg.WriteMask == WRITEMASK_Z ||
- inst->DstReg.WriteMask == WRITEMASK_W ||
- inst->DstReg.WriteMask == 0x0) {
- /* no chance of data dependency */
- return GL_FALSE;
- }
-
- /* loop over src regs */
- for (i = 0; i < 3; i++) {
- if (inst->SrcReg[i].File == inst->DstReg.File &&
- inst->SrcReg[i].Index == inst->DstReg.Index) {
- /* loop over dest channels */
- GLuint channelsWritten = 0x0;
- for (chan = 0; chan < 4; chan++) {
- if (inst->DstReg.WriteMask & (1 << chan)) {
- /* check if we're reading a channel that's been written */
- GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
- if (swizzle <= SWIZZLE_W &&
- (channelsWritten & (1 << swizzle))) {
- return GL_TRUE;
- }
-
- channelsWritten |= (1 << chan);
- }
- }
- }
- }
- return GL_FALSE;
-}
-
-
-/**
- * Return string name for given program opcode.
- */
-const char *
-_mesa_opcode_string(gl_inst_opcode opcode)
-{
- if (opcode < MAX_OPCODE)
- return InstInfo[opcode].Name;
- else {
- static char s[20];
- _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
- return s;
- }
-}
-
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 1999-2008 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.
- */
-
-
-/**
- * \file prog_instruction.h
- *
- * Vertex/fragment program instruction datatypes and constants.
- *
- * \author Brian Paul
- * \author Keith Whitwell
- * \author Ian Romanick <idr@us.ibm.com>
- */
-
-
-#ifndef PROG_INSTRUCTION_H
-#define PROG_INSTRUCTION_H
-
-
-#include "main/mtypes.h"
-
-
-/**
- * Swizzle indexes.
- * Do not change!
- */
-/*@{*/
-#define SWIZZLE_X 0
-#define SWIZZLE_Y 1
-#define SWIZZLE_Z 2
-#define SWIZZLE_W 3
-#define SWIZZLE_ZERO 4 /**< For SWZ instruction only */
-#define SWIZZLE_ONE 5 /**< For SWZ instruction only */
-#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */
-/*@}*/
-
-#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
-#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3)
-#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
-#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
-
-#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
-#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
-#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
-#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
-#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
-
-
-/**
- * Writemask values, 1 bit per component.
- */
-/*@{*/
-#define WRITEMASK_X 0x1
-#define WRITEMASK_Y 0x2
-#define WRITEMASK_XY 0x3
-#define WRITEMASK_Z 0x4
-#define WRITEMASK_XZ 0x5
-#define WRITEMASK_YZ 0x6
-#define WRITEMASK_XYZ 0x7
-#define WRITEMASK_W 0x8
-#define WRITEMASK_XW 0x9
-#define WRITEMASK_YW 0xa
-#define WRITEMASK_XYW 0xb
-#define WRITEMASK_ZW 0xc
-#define WRITEMASK_XZW 0xd
-#define WRITEMASK_YZW 0xe
-#define WRITEMASK_XYZW 0xf
-/*@}*/
-
-
-/**
- * Condition codes
- */
-/*@{*/
-#define COND_GT 1 /**< greater than zero */
-#define COND_EQ 2 /**< equal to zero */
-#define COND_LT 3 /**< less than zero */
-#define COND_UN 4 /**< unordered (NaN) */
-#define COND_GE 5 /**< greater than or equal to zero */
-#define COND_LE 6 /**< less than or equal to zero */
-#define COND_NE 7 /**< not equal to zero */
-#define COND_TR 8 /**< always true */
-#define COND_FL 9 /**< always false */
-/*@}*/
-
-
-/**
- * Instruction precision for GL_NV_fragment_program
- */
-/*@{*/
-#define FLOAT32 0x1
-#define FLOAT16 0x2
-#define FIXED12 0x4
-/*@}*/
-
-
-/**
- * Saturation modes when storing values.
- */
-/*@{*/
-#define SATURATE_OFF 0
-#define SATURATE_ZERO_ONE 1
-/*@}*/
-
-
-/**
- * Per-component negation masks
- */
-/*@{*/
-#define NEGATE_X 0x1
-#define NEGATE_Y 0x2
-#define NEGATE_Z 0x4
-#define NEGATE_W 0x8
-#define NEGATE_XYZ 0x7
-#define NEGATE_XYZW 0xf
-#define NEGATE_NONE 0x0
-/*@}*/
-
-
-/**
- * Program instruction opcodes, for both vertex and fragment programs.
- * \note changes to this opcode list must be reflected in t_vb_arbprogram.c
- */
-typedef enum prog_opcode {
- /* ARB_vp ARB_fp NV_vp NV_fp GLSL */
- /*------------------------------------------*/
- OPCODE_NOP = 0, /* X */
- OPCODE_ABS, /* X X 1.1 X */
- OPCODE_ADD, /* X X X X X */
- OPCODE_AND, /* */
- OPCODE_ARA, /* 2 */
- OPCODE_ARL, /* X X */
- OPCODE_ARL_NV, /* 2 */
- OPCODE_ARR, /* 2 */
- OPCODE_BGNLOOP, /* opt */
- OPCODE_BGNSUB, /* opt */
- OPCODE_BRA, /* 2 X */
- OPCODE_BRK, /* 2 opt */
- OPCODE_CAL, /* 2 2 */
- OPCODE_CMP, /* X */
- OPCODE_CONT, /* opt */
- OPCODE_COS, /* X 2 X X */
- OPCODE_DDX, /* X X */
- OPCODE_DDY, /* X X */
- OPCODE_DP2, /* 2 */
- OPCODE_DP2A, /* 2 */
- OPCODE_DP3, /* X X X X X */
- OPCODE_DP4, /* X X X X X */
- OPCODE_DPH, /* X X 1.1 */
- OPCODE_DST, /* X X X X */
- OPCODE_ELSE, /* X */
- OPCODE_END, /* X X X X opt */
- OPCODE_ENDIF, /* opt */
- OPCODE_ENDLOOP, /* opt */
- OPCODE_ENDSUB, /* opt */
- OPCODE_EX2, /* X X 2 X X */
- OPCODE_EXP, /* X X X */
- OPCODE_FLR, /* X X 2 X X */
- OPCODE_FRC, /* X X 2 X X */
- OPCODE_IF, /* opt */
- OPCODE_KIL, /* X */
- OPCODE_KIL_NV, /* X X */
- OPCODE_LG2, /* X X 2 X X */
- OPCODE_LIT, /* X X X X */
- OPCODE_LOG, /* X X X */
- OPCODE_LRP, /* X X */
- OPCODE_MAD, /* X X X X X */
- OPCODE_MAX, /* X X X X X */
- OPCODE_MIN, /* X X X X X */
- OPCODE_MOV, /* X X X X X */
- OPCODE_MUL, /* X X X X X */
- OPCODE_NOISE1, /* X */
- OPCODE_NOISE2, /* X */
- OPCODE_NOISE3, /* X */
- OPCODE_NOISE4, /* X */
- OPCODE_NOT, /* */
- OPCODE_NRM3, /* */
- OPCODE_NRM4, /* */
- OPCODE_OR, /* */
- OPCODE_PK2H, /* X */
- OPCODE_PK2US, /* X */
- OPCODE_PK4B, /* X */
- OPCODE_PK4UB, /* X */
- OPCODE_POW, /* X X X X */
- OPCODE_POPA, /* 3 */
- OPCODE_PRINT, /* X X */
- OPCODE_PUSHA, /* 3 */
- OPCODE_RCC, /* 1.1 */
- OPCODE_RCP, /* X X X X X */
- OPCODE_RET, /* 2 2 */
- OPCODE_RFL, /* X X */
- OPCODE_RSQ, /* X X X X X */
- OPCODE_SCS, /* X */
- OPCODE_SEQ, /* 2 X X */
- OPCODE_SFL, /* 2 X */
- OPCODE_SGE, /* X X X X X */
- OPCODE_SGT, /* 2 X X */
- OPCODE_SIN, /* X 2 X X */
- OPCODE_SLE, /* 2 X X */
- OPCODE_SLT, /* X X X X X */
- OPCODE_SNE, /* 2 X X */
- OPCODE_SSG, /* 2 */
- OPCODE_STR, /* 2 X */
- OPCODE_SUB, /* X X 1.1 X X */
- OPCODE_SWZ, /* X X */
- OPCODE_TEX, /* X 3 X X */
- OPCODE_TXB, /* X 3 X */
- OPCODE_TXD, /* X X */
- OPCODE_TXL, /* 3 2 X */
- OPCODE_TXP, /* X X */
- OPCODE_TXP_NV, /* 3 X */
- OPCODE_TRUNC, /* X */
- OPCODE_UP2H, /* X */
- OPCODE_UP2US, /* X */
- OPCODE_UP4B, /* X */
- OPCODE_UP4UB, /* X */
- OPCODE_X2D, /* X */
- OPCODE_XOR, /* */
- OPCODE_XPD, /* X X X */
- MAX_OPCODE
-} gl_inst_opcode;
-
-
-/**
- * Number of bits for the src/dst register Index field.
- * This limits the size of temp/uniform register files.
- */
-#define INST_INDEX_BITS 10
-
-
-/**
- * Instruction source register.
- */
-struct prog_src_register
-{
- GLuint File:4; /**< One of the PROGRAM_* register file values. */
- GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
- * May be negative for relative addressing.
- */
- GLuint Swizzle:12;
- GLuint RelAddr:1;
-
- /** Take the component-wise absolute value */
- GLuint Abs:1;
-
- /**
- * Post-Abs negation.
- * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ
- * instruction which allows per-component negation.
- */
- GLuint Negate:4;
-};
-
-
-/**
- * Instruction destination register.
- */
-struct prog_dst_register
-{
- GLuint File:4; /**< One of the PROGRAM_* register file values */
- GLuint Index:INST_INDEX_BITS; /**< Unsigned, never negative */
- GLuint WriteMask:4;
- GLuint RelAddr:1;
-
- /**
- * \name Conditional destination update control.
- *
- * \since
- * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
- * NV_vertex_program2_option.
- */
- /*@{*/
- /**
- * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
- * NE, TR, or UN). Dest reg is only written to if the matching
- * (swizzled) condition code value passes. When a conditional update mask
- * is not specified, this will be \c COND_TR.
- */
- GLuint CondMask:4;
-
- /**
- * Condition code swizzle value.
- */
- GLuint CondSwizzle:12;
-
- /**
- * Selects the condition code register to use for conditional destination
- * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only
- * condition code register 0 is available. In NV_vertex_program3 mode,
- * condition code registers 0 and 1 are available.
- */
- GLuint CondSrc:1;
- /*@}*/
-};
-
-
-/**
- * Vertex/fragment program instruction.
- */
-struct prog_instruction
-{
- gl_inst_opcode Opcode;
- struct prog_src_register SrcReg[3];
- struct prog_dst_register DstReg;
-
- /**
- * Indicates that the instruction should update the condition code
- * register.
- *
- * \since
- * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
- * NV_vertex_program2_option.
- */
- GLuint CondUpdate:1;
-
- /**
- * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
- * condition code register that is to be updated.
- *
- * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
- * code register 0 is available. In GL_NV_vertex_program3 mode, condition
- * code registers 0 and 1 are available.
- *
- * \since
- * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
- * NV_vertex_program2_option.
- */
- GLuint CondDst:1;
-
- /**
- * Saturate each value of the vectored result to the range [0,1] or the
- * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is
- * only available in NV_fragment_program2 mode.
- * Value is one of the SATURATE_* tokens.
- *
- * \since
- * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
- */
- GLuint SaturateMode:2;
-
- /**
- * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
- *
- * \since
- * NV_fragment_program, NV_fragment_program_option.
- */
- GLuint Precision:3;
-
- /**
- * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
- */
- /*@{*/
- /** Source texture unit. */
- GLuint TexSrcUnit:5;
-
- /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
- GLuint TexSrcTarget:3;
-
- /** True if tex instruction should do shadow comparison */
- GLuint TexShadow:1;
- /*@}*/
-
- /**
- * For BRA and CAL instructions, the location to jump to.
- * For BGNLOOP, points to ENDLOOP (and vice-versa).
- * For BRK, points to BGNLOOP (which points to ENDLOOP).
- * For IF, points to ELSE or ENDIF.
- * For ELSE, points to ENDIF.
- */
- GLint BranchTarget;
-
- /** for debugging purposes */
- const char *Comment;
-
- /** Arbitrary data. Used for OPCODE_PRINT and some drivers */
- void *Data;
-
- /** for driver use (try to remove someday) */
- GLint Aux;
-};
-
-
-extern void
-_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
-
-extern struct prog_instruction *
-_mesa_alloc_instructions(GLuint numInst);
-
-extern struct prog_instruction *
-_mesa_realloc_instructions(struct prog_instruction *oldInst,
- GLuint numOldInst, GLuint numNewInst);
-
-extern struct prog_instruction *
-_mesa_copy_instructions(struct prog_instruction *dest,
- const struct prog_instruction *src, GLuint n);
-
-extern void
-_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
-
-extern GLuint
-_mesa_num_inst_src_regs(gl_inst_opcode opcode);
-
-extern GLuint
-_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
-
-extern GLboolean
-_mesa_is_tex_instruction(gl_inst_opcode opcode);
-
-extern GLboolean
-_mesa_check_soa_dependencies(const struct prog_instruction *inst);
-
-extern const char *
-_mesa_opcode_string(gl_inst_opcode opcode);
-
-
-#endif /* PROG_INSTRUCTION_H */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * 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 prog_print.c
- * Print vertex/fragment programs - for debugging.
- * \author Brian Paul
- */
-
-#if 0
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#else
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-struct gl_program {
- int Target;
-};
-
-void _mesa_problem(void *ctx, char *msg)
-{
- (void)ctx;
- fprintf(stderr, "%s", msg);
- exit(1);
-}
-
-#endif
-
-#include "prog_instruction.h"
-#include "prog_print.h"
-
-
-
-/**
- * Return string name for given program/register file.
- */
-static const char *
-file_string(gl_register_file f, gl_prog_print_mode mode)
-{
- (void)mode;
- switch (f) {
- case PROGRAM_TEMPORARY:
- return "TEMP";
- case PROGRAM_LOCAL_PARAM:
- return "LOCAL";
- case PROGRAM_ENV_PARAM:
- return "ENV";
- case PROGRAM_STATE_VAR:
- return "STATE";
- case PROGRAM_INPUT:
- return "INPUT";
- case PROGRAM_OUTPUT:
- return "OUTPUT";
- case PROGRAM_NAMED_PARAM:
- return "NAMED";
- case PROGRAM_CONSTANT:
- return "CONST";
- case PROGRAM_UNIFORM:
- return "UNIFORM";
- case PROGRAM_VARYING:
- return "VARYING";
- case PROGRAM_WRITE_ONLY:
- return "WRITE_ONLY";
- case PROGRAM_ADDRESS:
- return "ADDR";
- case PROGRAM_SAMPLER:
- return "SAMPLER";
- case PROGRAM_UNDEFINED:
- return "UNDEFINED";
- default:
- {
- static char s[20];
- snprintf(s, sizeof(s), "FILE%u", f);
- return s;
- }
- }
-}
-
-
-/**
- * Return ARB_v/f_prog-style input attrib string.
- */
-static const char *
-arb_input_attrib_string(GLint index, GLenum progType)
-{
- /*
- * These strings should match the VERT_ATTRIB_x and FRAG_ATTRIB_x tokens.
- */
- const char *vertAttribs[] = {
- "vertex.position",
- "vertex.weight",
- "vertex.normal",
- "vertex.color.primary",
- "vertex.color.secondary",
- "vertex.fogcoord",
- "vertex.(six)",
- "vertex.(seven)",
- "vertex.texcoord[0]",
- "vertex.texcoord[1]",
- "vertex.texcoord[2]",
- "vertex.texcoord[3]",
- "vertex.texcoord[4]",
- "vertex.texcoord[5]",
- "vertex.texcoord[6]",
- "vertex.texcoord[7]",
- "vertex.attrib[0]",
- "vertex.attrib[1]",
- "vertex.attrib[2]",
- "vertex.attrib[3]",
- "vertex.attrib[4]",
- "vertex.attrib[5]",
- "vertex.attrib[6]",
- "vertex.attrib[7]",
- "vertex.attrib[8]",
- "vertex.attrib[9]",
- "vertex.attrib[10]",
- "vertex.attrib[11]",
- "vertex.attrib[12]",
- "vertex.attrib[13]",
- "vertex.attrib[14]",
- "vertex.attrib[15]"
- };
- const char *fragAttribs[] = {
- "fragment.position",
- "fragment.color.primary",
- "fragment.color.secondary",
- "fragment.fogcoord",
- "fragment.texcoord[0]",
- "fragment.texcoord[1]",
- "fragment.texcoord[2]",
- "fragment.texcoord[3]",
- "fragment.texcoord[4]",
- "fragment.texcoord[5]",
- "fragment.texcoord[6]",
- "fragment.texcoord[7]",
- "fragment.varying[0]",
- "fragment.varying[1]",
- "fragment.varying[2]",
- "fragment.varying[3]",
- "fragment.varying[4]",
- "fragment.varying[5]",
- "fragment.varying[6]",
- "fragment.varying[7]"
- };
-
- /* sanity checks */
- assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0);
- assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0);
-
- if (progType == GL_VERTEX_PROGRAM_ARB) {
- assert((unsigned int)index < sizeof(vertAttribs) / sizeof(vertAttribs[0]));
- return vertAttribs[index];
- }
- else {
- assert((unsigned int)index < sizeof(fragAttribs) / sizeof(fragAttribs[0]));
- return fragAttribs[index];
- }
-}
-
-
-/**
- * Print a vertex program's InputsRead field in human-readable format.
- * For debugging.
- */
-void
-_mesa_print_vp_inputs(GLbitfield inputs)
-{
- printf("VP Inputs 0x%x: \n", inputs);
- while (inputs) {
- GLint attr = ffs(inputs) - 1;
- const char *name = arb_input_attrib_string(attr,
- GL_VERTEX_PROGRAM_ARB);
- printf(" %d: %s\n", attr, name);
- inputs &= ~(1 << attr);
- }
-}
-
-
-/**
- * Print a fragment program's InputsRead field in human-readable format.
- * For debugging.
- */
-void
-_mesa_print_fp_inputs(GLbitfield inputs)
-{
- printf("FP Inputs 0x%x: \n", inputs);
- while (inputs) {
- GLint attr = ffs(inputs) - 1;
- const char *name = arb_input_attrib_string(attr,
- GL_FRAGMENT_PROGRAM_ARB);
- printf(" %d: %s\n", attr, name);
- inputs &= ~(1 << attr);
- }
-}
-
-
-#if 0
-/**
- * Return ARB_v/f_prog-style output attrib string.
- */
-static const char *
-arb_output_attrib_string(GLint index, GLenum progType)
-{
- /*
- * These strings should match the VERT_RESULT_x and FRAG_RESULT_x tokens.
- */
- const char *vertResults[] = {
- "result.position",
- "result.color.primary",
- "result.color.secondary",
- "result.fogcoord",
- "result.texcoord[0]",
- "result.texcoord[1]",
- "result.texcoord[2]",
- "result.texcoord[3]",
- "result.texcoord[4]",
- "result.texcoord[5]",
- "result.texcoord[6]",
- "result.texcoord[7]",
- "result.varying[0]",
- "result.varying[1]",
- "result.varying[2]",
- "result.varying[3]",
- "result.varying[4]",
- "result.varying[5]",
- "result.varying[6]",
- "result.varying[7]"
- };
- const char *fragResults[] = {
- "result.color",
- "result.color(half)",
- "result.depth",
- "result.color[0]",
- "result.color[1]",
- "result.color[2]",
- "result.color[3]"
- };
-
- if (progType == GL_VERTEX_PROGRAM_ARB) {
- assert(index < sizeof(vertResults) / sizeof(vertResults[0]));
- return vertResults[index];
- }
- else {
- assert(index < sizeof(fragResults) / sizeof(fragResults[0]));
- return fragResults[index];
- }
-}
-#endif
-
-/**
- * Return string representation of the given register.
- * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
- * by the ARB/NV program languages so we've taken some liberties here.
- * \param f the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
- * \param index number of the register in the register file
- * \param mode the output format/mode/style
- * \param prog pointer to containing program
- */
-static const char *
-reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
- GLboolean relAddr, const struct gl_program *prog)
-{
- static char str[100];
- const char *addr = relAddr ? "ADDR+" : "";
-
- str[0] = 0;
-
- switch (mode) {
- case PROG_PRINT_DEBUG:
- sprintf(str, "%s[%s%d]", file_string(f, mode), addr, index);
- break;
- case PROG_PRINT_ARB:
-#if 0
- switch (f) {
- case PROGRAM_INPUT:
- sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
- break;
- case PROGRAM_OUTPUT:
- sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
- break;
- case PROGRAM_TEMPORARY:
- sprintf(str, "temp%d", index);
- break;
- case PROGRAM_ENV_PARAM:
- sprintf(str, "program.env[%s%d]", addr, index);
- break;
- case PROGRAM_LOCAL_PARAM:
- sprintf(str, "program.local[%s%d]", addr, index);
- break;
- case PROGRAM_VARYING: /* extension */
- sprintf(str, "varying[%s%d]", addr, index);
- break;
- case PROGRAM_CONSTANT: /* extension */
- sprintf(str, "constant[%s%d]", addr, index);
- break;
- case PROGRAM_UNIFORM: /* extension */
- sprintf(str, "uniform[%s%d]", addr, index);
- break;
- case PROGRAM_STATE_VAR:
- {
- struct gl_program_parameter *param
- = prog->Parameters->Parameters + index;
- char *state = _mesa_program_state_string(param->StateIndexes);
- sprintf(str, "%s", state);
- free(state);
- }
- break;
- case PROGRAM_ADDRESS:
- sprintf(str, "A%d", index);
- break;
- default:
- _mesa_problem(NULL, "bad file in reg_string()");
- }
- break;
-#else
- assert(0);
- break;
-#endif
-
- case PROG_PRINT_NV:
- switch (f) {
- case PROGRAM_INPUT:
- if (prog->Target == GL_VERTEX_PROGRAM_ARB)
- sprintf(str, "v[%d]", index);
- else
- sprintf(str, "f[%d]", index);
- break;
- case PROGRAM_OUTPUT:
- sprintf(str, "o[%d]", index);
- break;
- case PROGRAM_TEMPORARY:
- sprintf(str, "R%d", index);
- break;
- case PROGRAM_ENV_PARAM:
- sprintf(str, "c[%d]", index);
- break;
- case PROGRAM_VARYING: /* extension */
- sprintf(str, "varying[%s%d]", addr, index);
- break;
- case PROGRAM_UNIFORM: /* extension */
- sprintf(str, "uniform[%s%d]", addr, index);
- break;
- case PROGRAM_CONSTANT: /* extension */
- sprintf(str, "constant[%s%d]", addr, index);
- break;
- case PROGRAM_STATE_VAR: /* extension */
- sprintf(str, "state[%s%d]", addr, index);
- break;
- default:
- _mesa_problem(NULL, "bad file in reg_string()");
- }
- break;
-
- default:
- _mesa_problem(NULL, "bad mode in reg_string()");
- }
-
- return str;
-}
-
-
-/**
- * Return a string representation of the given swizzle word.
- * If extended is true, use extended (comma-separated) format.
- * \param swizzle the swizzle field
- * \param negateBase 4-bit negation vector
- * \param extended if true, also allow 0, 1 values
- */
-const char *
-_mesa_swizzle_string(GLuint swizzle, GLuint negateMask, GLboolean extended)
-{
- static const char swz[] = "xyzw01!?"; /* See SWIZZLE_x definitions */
- static char s[20];
- GLuint i = 0;
-
- if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0)
- return ""; /* no swizzle/negation */
-
- if (!extended)
- s[i++] = '.';
-
- if (negateMask & NEGATE_X)
- s[i++] = '-';
- s[i++] = swz[GET_SWZ(swizzle, 0)];
-
- if (extended) {
- s[i++] = ',';
- }
-
- if (negateMask & NEGATE_Y)
- s[i++] = '-';
- s[i++] = swz[GET_SWZ(swizzle, 1)];
-
- if (extended) {
- s[i++] = ',';
- }
-
- if (negateMask & NEGATE_Z)
- s[i++] = '-';
- s[i++] = swz[GET_SWZ(swizzle, 2)];
-
- if (extended) {
- s[i++] = ',';
- }
-
- if (negateMask & NEGATE_W)
- s[i++] = '-';
- s[i++] = swz[GET_SWZ(swizzle, 3)];
-
- s[i] = 0;
- return s;
-}
-
-
-void
-_mesa_print_swizzle(GLuint swizzle)
-{
- if (swizzle == SWIZZLE_XYZW) {
- printf(".xyzw\n");
- }
- else {
- const char *s = _mesa_swizzle_string(swizzle, 0, 0);
- printf("%s\n", s);
- }
-}
-
-
-const char *
-_mesa_writemask_string(GLuint writeMask)
-{
- static char s[10];
- GLuint i = 0;
-
- if (writeMask == WRITEMASK_XYZW)
- return "";
-
- s[i++] = '.';
- if (writeMask & WRITEMASK_X)
- s[i++] = 'x';
- if (writeMask & WRITEMASK_Y)
- s[i++] = 'y';
- if (writeMask & WRITEMASK_Z)
- s[i++] = 'z';
- if (writeMask & WRITEMASK_W)
- s[i++] = 'w';
-
- s[i] = 0;
- return s;
-}
-
-
-const char *
-_mesa_condcode_string(GLuint condcode)
-{
- switch (condcode) {
- case COND_GT: return "GT";
- case COND_EQ: return "EQ";
- case COND_LT: return "LT";
- case COND_UN: return "UN";
- case COND_GE: return "GE";
- case COND_LE: return "LE";
- case COND_NE: return "NE";
- case COND_TR: return "TR";
- case COND_FL: return "FL";
- default: return "cond???";
- }
-}
-
-
-static void
-fprint_dst_reg(FILE * f,
- const struct prog_dst_register *dstReg,
- gl_prog_print_mode mode,
- const struct gl_program *prog)
-{
- fprintf(f, "%s%s",
- reg_string((gl_register_file) dstReg->File,
- dstReg->Index, mode, dstReg->RelAddr, prog),
- _mesa_writemask_string(dstReg->WriteMask));
-
- if (dstReg->CondMask != COND_TR) {
- fprintf(f, " (%s.%s)",
- _mesa_condcode_string(dstReg->CondMask),
- _mesa_swizzle_string(dstReg->CondSwizzle,
- GL_FALSE, GL_FALSE));
- }
-
-#if 0
- fprintf(f, "%s[%d]%s",
- file_string((gl_register_file) dstReg->File, mode),
- dstReg->Index,
- _mesa_writemask_string(dstReg->WriteMask));
-#endif
-}
-
-
-static void
-fprint_src_reg(FILE *f,
- const struct prog_src_register *srcReg,
- gl_prog_print_mode mode,
- const struct gl_program *prog)
-{
- const char *abs = srcReg->Abs ? "|" : "";
-
- fprintf(f, "%s%s%s%s",
- abs,
- reg_string((gl_register_file) srcReg->File,
- srcReg->Index, mode, srcReg->RelAddr, prog),
- _mesa_swizzle_string(srcReg->Swizzle,
- srcReg->Negate, GL_FALSE),
- abs);
-#if 0
- fprintf(f, "%s[%d]%s",
- file_string((gl_register_file) srcReg->File, mode),
- srcReg->Index,
- _mesa_swizzle_string(srcReg->Swizzle,
- srcReg->Negate, GL_FALSE));
-#endif
-}
-
-
-static void
-fprint_comment(FILE *f, const struct prog_instruction *inst)
-{
- if (inst->Comment)
- fprintf(f, "; # %s\n", inst->Comment);
- else
- fprintf(f, ";\n");
-}
-
-
-static void
-fprint_alu_instruction(FILE *f,
- const struct prog_instruction *inst,
- const char *opcode_string, GLuint numRegs,
- gl_prog_print_mode mode,
- const struct gl_program *prog)
-{
- GLuint j;
-
- fprintf(f, "%s", opcode_string);
- if (inst->CondUpdate)
- fprintf(f, ".C");
-
- /* frag prog only */
- if (inst->SaturateMode == SATURATE_ZERO_ONE)
- fprintf(f, "_SAT");
-
- fprintf(f, " ");
- if (inst->DstReg.File != PROGRAM_UNDEFINED) {
- fprint_dst_reg(f, &inst->DstReg, mode, prog);
- }
- else {
- fprintf(f, " ???");
- }
-
- if (numRegs > 0)
- fprintf(f, ", ");
-
- for (j = 0; j < numRegs; j++) {
- fprint_src_reg(f, inst->SrcReg + j, mode, prog);
- if (j + 1 < numRegs)
- fprintf(f, ", ");
- }
-
- fprint_comment(f, inst);
-}
-
-
-void
-_mesa_print_alu_instruction(const struct prog_instruction *inst,
- const char *opcode_string, GLuint numRegs)
-{
- fprint_alu_instruction(stderr, inst, opcode_string,
- numRegs, PROG_PRINT_DEBUG, NULL);
-}
-
-
-/**
- * Print a single vertex/fragment program instruction.
- */
-GLint
-_mesa_fprint_instruction_opt(FILE *f,
- const struct prog_instruction *inst,
- GLint indent,
- gl_prog_print_mode mode,
- const struct gl_program *prog)
-{
- GLint i;
-
- if (inst->Opcode == OPCODE_ELSE ||
- inst->Opcode == OPCODE_ENDIF ||
- inst->Opcode == OPCODE_ENDLOOP ||
- inst->Opcode == OPCODE_ENDSUB) {
- indent -= 3;
- }
- for (i = 0; i < indent; i++) {
- fprintf(f, " ");
- }
-
- switch (inst->Opcode) {
- case OPCODE_PRINT:
- fprintf(f, "PRINT '%s'", (char *) inst->Data);
- if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
- fprintf(f, ", ");
- fprintf(f, "%s[%d]%s",
- file_string((gl_register_file) inst->SrcReg[0].File,
- mode),
- inst->SrcReg[0].Index,
- _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
- inst->SrcReg[0].Negate, GL_FALSE));
- }
- if (inst->Comment)
- fprintf(f, " # %s", inst->Comment);
- fprint_comment(f, inst);
- break;
- case OPCODE_SWZ:
- fprintf(f, "SWZ");
- if (inst->SaturateMode == SATURATE_ZERO_ONE)
- fprintf(f, "_SAT");
- fprintf(f, " ");
- fprint_dst_reg(f, &inst->DstReg, mode, prog);
- fprintf(f, ", %s[%d], %s",
- file_string((gl_register_file) inst->SrcReg[0].File,
- mode),
- inst->SrcReg[0].Index,
- _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
- inst->SrcReg[0].Negate, GL_TRUE));
- fprint_comment(f, inst);
- break;
- case OPCODE_TEX:
- case OPCODE_TXP:
- case OPCODE_TXL:
- case OPCODE_TXB:
- fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
- if (inst->SaturateMode == SATURATE_ZERO_ONE)
- fprintf(f, "_SAT");
- fprintf(f, " ");
- fprint_dst_reg(f, &inst->DstReg, mode, prog);
- fprintf(f, ", ");
- fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
- fprintf(f, ", texture[%d], ", inst->TexSrcUnit);
- switch (inst->TexSrcTarget) {
- case TEXTURE_1D_INDEX: fprintf(f, "1D"); break;
- case TEXTURE_2D_INDEX: fprintf(f, "2D"); break;
- case TEXTURE_3D_INDEX: fprintf(f, "3D"); break;
- case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE"); break;
- case TEXTURE_RECT_INDEX: fprintf(f, "RECT"); break;
- case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break;
- case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break;
- default:
- ;
- }
- if (inst->TexShadow)
- fprintf(f, " SHADOW");
- fprint_comment(f, inst);
- break;
-
- case OPCODE_KIL:
- fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
- fprintf(f, " ");
- fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
- fprint_comment(f, inst);
- break;
- case OPCODE_KIL_NV:
- fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
- fprintf(f, " ");
- fprintf(f, "%s.%s",
- _mesa_condcode_string(inst->DstReg.CondMask),
- _mesa_swizzle_string(inst->DstReg.CondSwizzle,
- GL_FALSE, GL_FALSE));
- fprint_comment(f, inst);
- break;
-
- case OPCODE_ARL:
- fprintf(f, "ARL ");
- fprint_dst_reg(f, &inst->DstReg, mode, prog);
- fprintf(f, ", ");
- fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
- fprint_comment(f, inst);
- break;
- case OPCODE_BRA:
- fprintf(f, "BRA %d (%s%s)",
- inst->BranchTarget,
- _mesa_condcode_string(inst->DstReg.CondMask),
- _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
- fprint_comment(f, inst);
- break;
- case OPCODE_IF:
- if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
- /* Use ordinary register */
- fprintf(f, "IF ");
- fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
- fprintf(f, "; ");
- }
- else {
- /* Use cond codes */
- fprintf(f, "IF (%s%s);",
- _mesa_condcode_string(inst->DstReg.CondMask),
- _mesa_swizzle_string(inst->DstReg.CondSwizzle,
- 0, GL_FALSE));
- }
- fprintf(f, " # (if false, goto %d)", inst->BranchTarget);
- fprint_comment(f, inst);
- return indent + 3;
- case OPCODE_ELSE:
- fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget);
- return indent + 3;
- case OPCODE_ENDIF:
- fprintf(f, "ENDIF;\n");
- break;
- case OPCODE_BGNLOOP:
- fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget);
- return indent + 3;
- case OPCODE_ENDLOOP:
- fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget);
- break;
- case OPCODE_BRK:
- case OPCODE_CONT:
- fprintf(f, "%s (%s%s); # (goto %d)",
- _mesa_opcode_string(inst->Opcode),
- _mesa_condcode_string(inst->DstReg.CondMask),
- _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
- inst->BranchTarget);
- fprint_comment(f, inst);
- break;
-
- case OPCODE_BGNSUB:
- if (mode == PROG_PRINT_NV) {
- fprintf(f, "%s:\n", inst->Comment); /* comment is label */
- return indent;
- }
- else {
- fprintf(f, "BGNSUB");
- fprint_comment(f, inst);
- return indent + 3;
- }
- case OPCODE_ENDSUB:
- if (mode == PROG_PRINT_DEBUG) {
- fprintf(f, "ENDSUB");
- fprint_comment(f, inst);
- }
- break;
- case OPCODE_CAL:
- if (mode == PROG_PRINT_NV) {
- fprintf(f, "CAL %s; # (goto %d)\n", inst->Comment, inst->BranchTarget);
- }
- else {
- fprintf(f, "CAL %u", inst->BranchTarget);
- fprint_comment(f, inst);
- }
- break;
- case OPCODE_RET:
- fprintf(f, "RET (%s%s)",
- _mesa_condcode_string(inst->DstReg.CondMask),
- _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
- fprint_comment(f, inst);
- break;
-
- case OPCODE_END:
- fprintf(f, "END\n");
- break;
- case OPCODE_NOP:
- if (mode == PROG_PRINT_DEBUG) {
- fprintf(f, "NOP");
- fprint_comment(f, inst);
- }
- else if (inst->Comment) {
- /* ARB/NV extensions don't have NOP instruction */
- fprintf(f, "# %s\n", inst->Comment);
- }
- break;
- /* XXX may need other special-case instructions */
- default:
- if (inst->Opcode < MAX_OPCODE) {
- /* typical alu instruction */
- fprint_alu_instruction(f, inst,
- _mesa_opcode_string(inst->Opcode),
- _mesa_num_inst_src_regs(inst->Opcode),
- mode, prog);
- }
- else {
- fprint_alu_instruction(f, inst,
- _mesa_opcode_string(inst->Opcode),
- 3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
- mode, prog);
- }
- break;
- }
- return indent;
-}
-
-
-GLint
-_mesa_print_instruction_opt(const struct prog_instruction *inst,
- GLint indent,
- gl_prog_print_mode mode,
- const struct gl_program *prog)
-{
- return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog);
-}
-
-
-void
-_mesa_print_instruction(const struct prog_instruction *inst)
-{
- /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
- _mesa_fprint_instruction_opt(stdout, inst, 0, PROG_PRINT_DEBUG, NULL);
-}
-
-#if 0
-/**
- * Print program, with options.
- */
-void
-_mesa_fprint_program_opt(FILE *f,
- const struct gl_program *prog,
- gl_prog_print_mode mode,
- GLboolean lineNumbers)
-{
- GLuint i, indent = 0;
-
- switch (prog->Target) {
- case GL_VERTEX_PROGRAM_ARB:
- if (mode == PROG_PRINT_ARB)
- fprintf(f, "!!ARBvp1.0\n");
- else if (mode == PROG_PRINT_NV)
- fprintf(f, "!!VP1.0\n");
- else
- fprintf(f, "# Vertex Program/Shader %u\n", prog->Id);
- break;
- case GL_FRAGMENT_PROGRAM_ARB:
- case GL_FRAGMENT_PROGRAM_NV:
- if (mode == PROG_PRINT_ARB)
- fprintf(f, "!!ARBfp1.0\n");
- else if (mode == PROG_PRINT_NV)
- fprintf(f, "!!FP1.0\n");
- else
- fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
- break;
- }
-
- for (i = 0; i < prog->NumInstructions; i++) {
- if (lineNumbers)
- fprintf(f, "%3d: ", i);
- indent = _mesa_fprint_instruction_opt(f, prog->Instructions + i,
- indent, mode, prog);
- }
-}
-
-
-/**
- * Print program to stderr, default options.
- */
-void
-_mesa_print_program(const struct gl_program *prog)
-{
- _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
-}
-
-/**
- * Return binary representation of 64-bit value (as a string).
- * Insert a comma to separate each group of 8 bits.
- * Note we return a pointer to local static storage so this is not
- * re-entrant, etc.
- * XXX move to imports.[ch] if useful elsewhere.
- */
-static const char *
-binary(GLbitfield64 val)
-{
- static char buf[80];
- GLint i, len = 0;
- for (i = 63; i >= 0; --i) {
- if (val & (1ULL << i))
- buf[len++] = '1';
- else if (len > 0 || i == 0)
- buf[len++] = '0';
- if (len > 0 && ((i-1) % 8) == 7)
- buf[len++] = ',';
- }
- buf[len] = '\0';
- return buf;
-}
-
-
-/**
- * Print all of a program's parameters/fields to given file.
- */
-static void
-_mesa_fprint_program_parameters(FILE *f,
- GLcontext *ctx,
- const struct gl_program *prog)
-{
- GLuint i;
-
- fprintf(f, "InputsRead: 0x%x (0b%s)\n",
- prog->InputsRead, binary(prog->InputsRead));
- fprintf(f, "OutputsWritten: 0x%llx (0b%s)\n",
- prog->OutputsWritten, binary(prog->OutputsWritten));
- fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
- fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
- fprintf(f, "NumParameters=%d\n", prog->NumParameters);
- fprintf(f, "NumAttributes=%d\n", prog->NumAttributes);
- fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs);
- fprintf(f, "SamplersUsed: 0x%x (0b%s)\n",
- prog->SamplersUsed, binary(prog->SamplersUsed));
- fprintf(f, "Samplers=[ ");
- for (i = 0; i < MAX_SAMPLERS; i++) {
- fprintf(f, "%d ", prog->SamplerUnits[i]);
- }
- fprintf(f, "]\n");
-
- _mesa_load_state_parameters(ctx, prog->Parameters);
-
-#if 0
- fprintf(f, "Local Params:\n");
- for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
- const GLfloat *p = prog->LocalParams[i];
- fprintf(f, "%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
- }
-#endif
- _mesa_print_parameter_list(prog->Parameters);
-}
-
-
-/**
- * Print all of a program's parameters/fields to stderr.
- */
-void
-_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
-{
- _mesa_fprint_program_parameters(stderr, ctx, prog);
-}
-
-
-/**
- * Print a program parameter list to given file.
- */
-static void
-_mesa_fprint_parameter_list(FILE *f,
- const struct gl_program_parameter_list *list)
-{
- const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
- GLuint i;
-
- if (!list)
- return;
-
- if (0)
- fprintf(f, "param list %p\n", (void *) list);
- fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags);
- for (i = 0; i < list->NumParameters; i++){
- struct gl_program_parameter *param = list->Parameters + i;
- const GLfloat *v = list->ParameterValues[i];
- fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}",
- i, param->Size,
- file_string(list->Parameters[i].Type, mode),
- param->Name, v[0], v[1], v[2], v[3]);
- if (param->Flags & PROG_PARAM_BIT_CENTROID)
- fprintf(f, " Centroid");
- if (param->Flags & PROG_PARAM_BIT_INVARIANT)
- fprintf(f, " Invariant");
- if (param->Flags & PROG_PARAM_BIT_FLAT)
- fprintf(f, " Flat");
- if (param->Flags & PROG_PARAM_BIT_LINEAR)
- fprintf(f, " Linear");
- fprintf(f, "\n");
- }
-}
-
-
-/**
- * Print a program parameter list to stderr.
- */
-void
-_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
-{
- _mesa_fprint_parameter_list(stderr, list);
-}
-
-
-/**
- * Write shader and associated info to a file.
- */
-void
-_mesa_write_shader_to_file(const struct gl_shader *shader)
-{
- const char *type;
- char filename[100];
- FILE *f;
-
- if (shader->Type == GL_FRAGMENT_SHADER)
- type = "frag";
- else
- type = "vert";
-
- snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
- f = fopen(filename, "w");
- if (!f) {
- fprintf(stderr, "Unable to open %s for writing\n", filename);
- return;
- }
-
- fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
- fputs(shader->Source, f);
- fprintf(f, "\n");
-
- fprintf(f, "/* Compile status: %s */\n",
- shader->CompileStatus ? "ok" : "fail");
- if (!shader->CompileStatus) {
- fprintf(f, "/* Log Info: */\n");
- fputs(shader->InfoLog, f);
- }
- else {
- fprintf(f, "/* GPU code */\n");
- fprintf(f, "/*\n");
- _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
- fprintf(f, "*/\n");
- fprintf(f, "/* Parameters / constants */\n");
- fprintf(f, "/*\n");
- _mesa_fprint_parameter_list(f, shader->Program->Parameters);
- fprintf(f, "*/\n");
- }
-
- fclose(f);
-}
-
-
-/**
- * Append the shader's uniform info/values to the shader log file.
- * The log file will typically have been created by the
- * _mesa_write_shader_to_file function.
- */
-void
-_mesa_append_uniforms_to_file(const struct gl_shader *shader,
- const struct gl_program *prog)
-{
- const char *type;
- char filename[100];
- FILE *f;
-
- if (shader->Type == GL_FRAGMENT_SHADER)
- type = "frag";
- else
- type = "vert";
-
- snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
- f = fopen(filename, "a"); /* append */
- if (!f) {
- fprintf(stderr, "Unable to open %s for appending\n", filename);
- return;
- }
-
- fprintf(f, "/* First-draw parameters / constants */\n");
- fprintf(f, "/*\n");
- _mesa_fprint_parameter_list(f, prog->Parameters);
- fprintf(f, "*/\n");
-
- fclose(f);
-}
-#endif
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 1999-2007 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.
- */
-
-
-#ifndef PROG_PRINT_H
-#define PROG_PRINT_H
-
-
-/**
- * The output style to use when printing programs.
- */
-typedef enum {
- PROG_PRINT_ARB,
- PROG_PRINT_NV,
- PROG_PRINT_DEBUG
-} gl_prog_print_mode;
-
-
-extern void
-_mesa_print_vp_inputs(GLbitfield inputs);
-
-extern void
-_mesa_print_fp_inputs(GLbitfield inputs);
-
-extern const char *
-_mesa_condcode_string(GLuint condcode);
-
-extern const char *
-_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
-
-const char *
-_mesa_writemask_string(GLuint writeMask);
-
-extern void
-_mesa_print_swizzle(GLuint swizzle);
-
-extern void
-_mesa_print_alu_instruction(const struct prog_instruction *inst,
- const char *opcode_string, GLuint numRegs);
-
-extern void
-_mesa_print_instruction(const struct prog_instruction *inst);
-
-extern GLint
-_mesa_fprint_instruction_opt(FILE *f,
- const struct prog_instruction *inst,
- GLint indent,
- gl_prog_print_mode mode,
- const struct gl_program *prog);
-
-extern GLint
-_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
- gl_prog_print_mode mode,
- const struct gl_program *prog);
-
-extern void
-_mesa_print_program(const struct gl_program *prog);
-
-extern void
-_mesa_fprint_program_opt(FILE *f,
- const struct gl_program *prog, gl_prog_print_mode mode,
- GLboolean lineNumbers);
-
-#if 0
-extern void
-_mesa_print_parameter_list(const struct gl_program_parameter_list *list);
-
-extern void
-_mesa_write_shader_to_file(const struct gl_shader *shader);
-
-extern void
-_mesa_append_uniforms_to_file(const struct gl_shader *shader,
- const struct gl_program *prog);
-#endif
-
-
-#endif /* PROG_PRINT_H */
+++ /dev/null
-/*
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
- * 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 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.
- */
-
-#include <GL/gl.h>
-#include "main/mtypes.h"
-
-/**
- * Based on gl_shader in Mesa's mtypes.h.
- */
-struct glsl_shader {
- GLenum Type;
- GLuint Name;
- GLint RefCount;
- GLboolean DeletePending;
- GLboolean CompileStatus;
- const GLchar *Source; /**< Source code string */
- size_t SourceLen;
- GLchar *InfoLog;
-
- struct exec_list ir;
- struct glsl_symbol_table *symbols;
-};
-
-
-typedef int gl_state_index;
-#define STATE_LENGTH 5
-
-/**
- * Program parameter.
- * Used by shaders/programs for uniforms, constants, varying vars, etc.
- */
-struct gl_program_parameter
-{
- const char *Name; /**< Null-terminated string */
- gl_register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */
- GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
- /**
- * Number of components (1..4), or more.
- * If the number of components is greater than 4,
- * this parameter is part of a larger uniform like a GLSL matrix or array.
- * The next program parameter's Size will be Size-4 of this parameter.
- */
- GLuint Size;
- GLboolean Used; /**< Helper flag for GLSL uniform tracking */
- GLboolean Initialized; /**< Has the ParameterValue[] been set? */
- GLbitfield Flags; /**< Bitmask of PROG_PARAM_*_BIT */
- /**
- * A sequence of STATE_* tokens and integers to identify GL state.
- */
- gl_state_index StateIndexes[STATE_LENGTH];
-};
-
-
-/**
- * List of gl_program_parameter instances.
- */
-struct gl_program_parameter_list
-{
- GLuint Size; /**< allocated size of Parameters, ParameterValues */
- GLuint NumParameters; /**< number of parameters in arrays */
- struct gl_program_parameter *Parameters; /**< Array [Size] */
- GLfloat (*ParameterValues)[4]; /**< Array [Size] of GLfloat[4] */
- GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
- might invalidate ParameterValues[] */
-};
-
-
-/**
- * Shader program uniform variable.
- * The glGetUniformLocation() and glUniform() commands will use this
- * information.
- * Note that a uniform such as "binormal" might be used in both the
- * vertex shader and the fragment shader. When glUniform() is called to
- * set the uniform's value, it must be updated in both the vertex and
- * fragment shaders. The uniform may be in different locations in the
- * two shaders so we keep track of that here.
- */
-struct gl_uniform
-{
- const char *Name; /**< Null-terminated string */
- GLint VertPos;
- GLint FragPos;
- GLboolean Initialized; /**< For debug. Has this uniform been set? */
-#if 0
- GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
- GLuint Size; /**< Number of components (1..4) */
-#endif
-};
-
-
-/**
- * List of gl_uniforms
- */
-struct gl_uniform_list
-{
- GLuint Size; /**< allocated size of Uniforms array */
- GLuint NumUniforms; /**< number of uniforms in the array */
- struct gl_uniform *Uniforms; /**< Array [Size] */
-};
-
-
-/**
- * Based on gl_shader_program in Mesa's mtypes.h.
- */
-struct glsl_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 glsl_shader **Shaders; /**< List of attached the shaders */
-
- /**
- * Per-stage shaders resulting from the first stage of linking.
- */
- /*@{*/
- unsigned _NumLinkedShaders;
- struct glsl_shader **_LinkedShaders;
- /*@}*/
-
- /** User-defined attribute bindings (glBindAttribLocation) */
- struct gl_program_parameter_list *Attributes;
-
- /* post-link info: */
- 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;
-};
-
-extern void
-link_shaders(struct glsl_program *prog);
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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 <cstdlib>
-#include <cstring>
-#include <assert.h>
-#include "s_expression.h"
-
-s_symbol::s_symbol(const char *tmp)
-{
- this->str = talloc_strdup (this, tmp);
- assert(this->str != NULL);
-}
-
-s_list::s_list()
-{
-}
-
-unsigned
-s_list::length() const
-{
- unsigned i = 0;
- foreach_iter(exec_list_iterator, it, this->subexpressions) {
- i++;
- }
- return i;
-}
-
-static s_expression *
-read_atom(void *ctx, const char *& src)
-{
- char buf[101];
- int n;
- if (sscanf(src, " %100[^( \v\t\r\n)]%n", buf, &n) != 1)
- return NULL; // no atom
- src += n;
-
- // Check if the atom is a number.
- char *float_end = NULL;
- double f = strtod(buf, &float_end);
- if (float_end != buf) {
- char *int_end = NULL;
- int i = strtol(buf, &int_end, 10);
- // If strtod matched more characters, it must have a decimal part
- if (float_end > int_end)
- return new(ctx) s_float(f);
-
- return new(ctx) s_int(i);
- }
- // Not a number; return a symbol.
- return new(ctx) s_symbol(buf);
-}
-
-s_expression *
-s_expression::read_expression(void *ctx, const char *&src)
-{
- assert(src != NULL);
-
- s_expression *atom = read_atom(ctx, src);
- if (atom != NULL)
- return atom;
-
- char c;
- int n;
- if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') {
- src += n;
-
- s_list *list = new(ctx) s_list;
- s_expression *expr;
-
- while ((expr = read_expression(ctx, src)) != NULL) {
- list->subexpressions.push_tail(expr);
- }
- if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') {
- printf("Unclosed expression (check your parenthesis).\n");
- return NULL;
- }
- src += n;
- return list;
- }
- return NULL;
-}
-
-void s_int::print()
-{
- printf("%d", this->val);
-}
-
-void s_float::print()
-{
- printf("%f", this->val);
-}
-
-void s_symbol::print()
-{
- printf("%s", this->str);
-}
-
-void s_list::print()
-{
- printf("(");
- foreach_iter(exec_list_iterator, it, this->subexpressions) {
- s_expression *expr = (s_expression*) it.get();
- expr->print();
- printf(" ");
- }
- printf(")");
-}
-
+++ /dev/null
-/* -*- c++ -*- */
-/*
- * 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.
- */
-
-#pragma once
-#ifndef S_EXPRESSION_H
-#define S_EXPRESSION_H
-
-#include "list.h"
-
-#define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \
- : NULL
-#define SX_AS_LIST(x) SX_AS_(list, x)
-#define SX_AS_SYMBOL(x) SX_AS_(symbol, x)
-#define SX_AS_NUMBER(x) SX_AS_(number, x)
-#define SX_AS_INT(x) SX_AS_(int, x)
-
-/* For our purposes, S-Expressions are:
- * - <int>
- * - <float>
- * - symbol
- * - (expr1 expr2 ... exprN) where exprN is an S-Expression
- *
- * Unlike LISP/Scheme, we do not support (foo . bar) pairs.
- */
-class s_expression : public exec_node
-{
-public:
- /**
- * Read an S-Expression from the given string.
- * Advances the supplied pointer to just after the expression read.
- *
- * Any allocation will be performed with 'ctx' as the talloc owner.
- */
- static s_expression *read_expression(void *ctx, const char *&src);
-
- /**
- * Print out an S-Expression. Useful for debugging.
- */
- virtual void print() = 0;
-
- virtual bool is_list() const { return false; }
- virtual bool is_symbol() const { return false; }
- virtual bool is_number() const { return false; }
- virtual bool is_int() const { return false; }
-
-protected:
- s_expression() { }
-};
-
-/* Atoms */
-
-class s_number : public s_expression
-{
-public:
- bool is_number() const { return true; }
-
- virtual float fvalue() = 0;
-
-protected:
- s_number() { }
-};
-
-class s_int : public s_number
-{
-public:
- s_int(int x) : val(x) { }
-
- bool is_int() const { return true; }
-
- float fvalue() { return float(this->val); }
- int value() { return this->val; }
-
- void print();
-
-private:
- int val;
-};
-
-class s_float : public s_number
-{
-public:
- s_float(float x) : val(x) { }
-
- float fvalue() { return this->val; }
-
- void print();
-
-private:
- float val;
-};
-
-class s_symbol : public s_expression
-{
-public:
- s_symbol(const char *);
-
- bool is_symbol() const { return true; }
-
- const char *value() { return this->str; }
-
- void print();
-
-private:
- char *str;
-};
-
-/* Lists of expressions: (expr1 ... exprN) */
-class s_list : public s_expression
-{
-public:
- s_list();
-
- virtual bool is_list() const { return true; }
- unsigned length() const;
-
- void print();
-
- exec_list subexpressions;
-};
-
-#endif /* S_EXPRESSION_H */
--- /dev/null
+((c-mode . ((c-basic-offset . 3)))
+ (c++-mode . ((c-basic-offset . 3)))
+)
--- /dev/null
+.deps
+COPYING
+INSTALL
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.*
+configure
+depcomp
+ylwrap
+install-sh
+missing
+stamp-h1
+libtool
+ltmain.sh
+Makefile
+*.o
+*~
+glsl_lexer.cpp
+glsl_parser.output
+glsl_parser.cpp
+glsl_parser.h
+glsl
+mesa_codegen.cpp
+mesa_codegen.h
--- /dev/null
+# Copyright © 2010 Intel Corporation
+# 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
+# on 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
+# AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR 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.
+
+AUTOMAKE_OPTIONS = foreign
+AM_CPPFLAGS = -I mesa
+
+SUBDIRS = glcpp
+
+bin_PROGRAMS = glsl
+
+glsl_LDADD = ./glcpp/libglcpp.la
+glsl_LDFLAGS = @LDFLAGS@ $(talloc_LIBS)
+glsl_SOURCES = \
+ main.cpp \
+ builtin_types.h \
+ symbol_table.c hash_table.c glsl_types.cpp \
+ glsl_parser.ypp glsl_lexer.lpp glsl_parser_extras.cpp \
+ ast_expr.cpp ast_to_hir.cpp ast_function.cpp ast_type.cpp \
+ ir.cpp hir_field_selection.cpp builtin_function.cpp \
+ ir_print_visitor.cpp ir_variable.cpp ir_function.cpp \
+ ir_basic_block.cpp \
+ ir_basic_block.h \
+ ir_clone.cpp \
+ ir_constant_expression.cpp \
+ ir_constant_folding.cpp \
+ ir_constant_variable.cpp \
+ ir_copy_propagation.cpp \
+ ir_copy_propagation.h \
+ ir_dead_code.cpp \
+ ir_dead_code.h \
+ ir_dead_code_local.cpp \
+ ir_expression_flattening.cpp \
+ ir_function_can_inline.cpp \
+ ir_function_inlining.cpp \
+ ir_if_simplification.cpp \
+ ir_optimization.h \
+ ir_reader.cpp s_expression.cpp \
+ ir_hv_accept.cpp \
+ ir_hierarchical_visitor.h \
+ ir_hierarchical_visitor.cpp \
+ ir_swizzle_swizzle.cpp \
+ ir_to_mesa.cpp \
+ ir_to_mesa.h \
+ ir_validate.cpp \
+ ir_vec_index_to_swizzle.cpp \
+ linker.cpp \
+ mesa/shader/prog_instruction.c \
+ mesa/shader/prog_instruction.h \
+ mesa/shader/prog_print.c \
+ mesa/shader/prog_print.h
+
+BUILT_SOURCES = glsl_parser.h glsl_parser.cpp glsl_lexer.cpp
+CLEANFILES = $(BUILT_SOURCES)
+
+builtin_function.cpp: builtins/*/*
+ ./builtins/tools/generate_builtins.pl > builtin_function.cpp
+glsl_parser.h: glsl_parser.cpp
+
+.lpp.cpp:
+ $(LEXCOMPILE) --outfile="$@" $<
--- /dev/null
+- Implement AST-to-HIR conversion of discard instructions.
+
+- Handle constant expressions of (matrix {+,-,*,/} scalar)
+
+- Handle constant expressions of (vector {+,-,*,/} scalar)
+
+- Handle constant expressions of (matrix * vector)
+
+- Handle constant expressions of (matrix * matrix)
+
+- Handle currently unsupported constant expression types
+ - ir_unop_sign
+ - ir_unop_exp2
+ - ir_unop_log2
+ - ir_unop_u2f
+ - ir_unop_trunc
+ - ir_unop_ceil
+ - ir_unop_floor
+ - ir_unop_sin
+ - ir_unop_cos
+ - ir_binop_dot
+ - ir_binop_min
+ - ir_binop_max
+ - ir_binop_pow
+
+- Handle constant expressions of (struct == struct)
+
+- Handle constant expressions of (struct != struct)
+
+- Add support to ir_constant for array constants Arrays can only be
+ - declared 'const' in GLSL 1.20+. This is because there are no
+ array constructors in GLSL 1.10, and any variable declared as
+ 'const' must have an initializer.
+
+- Handle constant expressions of (array == array)
+
+- Handle constant expressions of (array != array)
+
+- Treat built-in functions with constant parameters as constant expressions.
+ - Rewrite all built-in functions return a single expression.
+ - Modify the HIR generator for functions to automatically inline built-in
+ functions durning translation.
+ - Care must be taken to handle both the 1.10 rules and the 1.20+ rules. In
+ 1.10, built-in functions cannot be constant expressions.
+
+- Detect non-void functions that lack a return statement
+
+- Detect return statements with a type not matching the funciton's
+ return type.
+
+- Handle over-riding built-in functions
+ - Is the overload per-compilation unit or per-linked shader?
+
+- Handle redeclaration of built-in variables
+ - Handle addition of qualifiers such as 'invariant' or 'centroid'.
+ - Handle resizing of arrays.
+ - Other? We'll have to look at the spec.
+
+- Improve handling of constants and their initializers. Constant initializers
+ should never generate any code. This is trival for scalar constants. It is
+ also trivial for arrays, matrices, and vectors that are accessed with
+ constant index values. For others it is more complicated. Perhaps these
+ cases should be silently converted to uniforms?
+
+1.30 features:
+
+- Implement AST-to-HIR conversion of bit-shift operators.
+
+- Implement AST-to-HIR conversion of bit-wise {&,|,^,!} operators.
+
+- Implement AST-to-HIR conversion of switch-statements
+ - switch
+ - case
+ - Update break to correcly handle mixed nexting of switch-statements
+ and loops.
+
+- Handle currently unsupported constant expression types
+ - ir_unop_bit_not
+ - ir_binop_mod
+ - ir_binop_lshift
+ - ir_binop_rshift
+ - ir_binop_bit_and
+ - ir_binop_bit_xor
+ - ir_binop_bit_or
--- /dev/null
+/* -*- 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 ir_instruction;
+struct _mesa_glsl_parse_state;
+
+struct YYLTYPE;
+
+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_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);
+ }
+
+ virtual void print(void) const;
+ 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;
+ }
+
+ struct {
+ unsigned source;
+ unsigned line;
+ unsigned column;
+ } location;
+
+ exec_node link;
+
+protected:
+ ast_node(void);
+};
+
+
+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
+};
+
+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 {
+ 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;
+};
+
+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;
+
+ 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:
+ 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 struct ir_rvalue *
+_mesa_ast_field_selection_to_hir(const struct ast_expression *expr,
+ exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+#endif /* AST_H */
--- /dev/null
+/*
+ * 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 <cassert>
+#include "ast.h"
+
+const char *
+ast_expression::operator_string(enum ast_operators op)
+{
+ static const char *const operators[] = {
+ "=",
+ "+",
+ "-",
+ "+",
+ "-",
+ "*",
+ "/",
+ "%",
+ "<<",
+ ">>",
+ "<",
+ ">",
+ "<=",
+ ">=",
+ "==",
+ "!=",
+ "&",
+ "^",
+ "|",
+ "~",
+ "&&",
+ "^^",
+ "||",
+ "!",
+
+ "*=",
+ "/=",
+ "%=",
+ "+=",
+ "-=",
+ "<<=",
+ ">>=",
+ "&=",
+ "^=",
+ "|=",
+
+ "?:",
+
+ "++",
+ "--",
+ "++",
+ "--",
+ ".",
+ };
+
+ assert((unsigned int)op < sizeof(operators) / sizeof(operators[0]));
+
+ return operators[op];
+}
+
+
+ast_expression_bin::ast_expression_bin(int oper, ast_expression *ex0,
+ ast_expression *ex1) :
+ ast_expression(oper, ex0, ex1, NULL)
+{
+ assert((oper >= ast_plus) && (oper <= ast_logic_not));
+}
+
+
+void
+ast_expression_bin::print(void) const
+{
+ subexpressions[0]->print();
+ printf("%s ", operator_string(oper));
+ subexpressions[1]->print();
+}
--- /dev/null
+/*
+ * 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_symbol_table.h"
+#include "ast.h"
+#include "glsl_types.h"
+#include "ir.h"
+
+static unsigned
+process_parameters(exec_list *instructions, exec_list *actual_parameters,
+ exec_list *parameters,
+ struct _mesa_glsl_parse_state *state)
+{
+ unsigned count = 0;
+
+ foreach_list (n, parameters) {
+ ast_node *const ast = exec_node_data(ast_node, n, link);
+ ir_rvalue *result = ast->hir(instructions, state);
+
+ ir_constant *const constant = result->constant_expression_value();
+ if (constant != NULL)
+ result = constant;
+
+ actual_parameters->push_tail(result);
+ count++;
+ }
+
+ return count;
+}
+
+
+static ir_rvalue *
+process_call(exec_list *instructions, ir_function *f,
+ YYLTYPE *loc, exec_list *actual_parameters,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+
+ const ir_function_signature *sig =
+ f->matching_signature(actual_parameters);
+
+ /* The instructions param will be used when the FINISHMEs below are done */
+ (void) instructions;
+
+ if (sig != NULL) {
+ /* Verify that 'out' and 'inout' actual parameters are lvalues. This
+ * isn't done in ir_function::matching_signature because that function
+ * cannot generate the necessary diagnostics.
+ */
+ exec_list_iterator actual_iter = actual_parameters->iterator();
+ exec_list_iterator formal_iter = sig->parameters.iterator();
+
+ while (actual_iter.has_next()) {
+ ir_rvalue *actual = (ir_rvalue *) actual_iter.get();
+ ir_variable *formal = (ir_variable *) formal_iter.get();
+
+ assert(actual != NULL);
+ assert(formal != NULL);
+
+ if ((formal->mode == ir_var_out)
+ || (formal->mode == ir_var_inout)) {
+ if (! actual->is_lvalue()) {
+ /* FINISHME: Log a better diagnostic here. There is no way
+ * FINISHME: to tell the user which parameter is invalid.
+ */
+ _mesa_glsl_error(loc, state, "`%s' parameter is not lvalue",
+ (formal->mode == ir_var_out) ? "out" : "inout");
+ }
+ }
+
+ actual_iter.next();
+ formal_iter.next();
+ }
+
+ /* FINISHME: The list of actual parameters needs to be modified to
+ * FINISHME: include any necessary conversions.
+ */
+ return new(ctx) ir_call(sig, actual_parameters);
+ } else {
+ /* FINISHME: Log a better error message here. G++ will show the types
+ * FINISHME: of the actual parameters and the set of candidate
+ * FINISHME: functions. A different error should also be logged when
+ * FINISHME: multiple functions match.
+ */
+ _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
+ f->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+}
+
+
+static ir_rvalue *
+match_function_by_name(exec_list *instructions, const char *name,
+ YYLTYPE *loc, exec_list *actual_parameters,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ ir_function *f = state->symbols->get_function(name);
+
+ if (f == NULL) {
+ _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ /* Once we've determined that the function being called might exist, try
+ * to find an overload of the function that matches the parameters.
+ */
+ return process_call(instructions, f, loc, actual_parameters, state);
+}
+
+
+/**
+ * Perform automatic type conversion of constructor parameters
+ */
+static ir_rvalue *
+convert_component(ir_rvalue *src, const glsl_type *desired_type)
+{
+ void *ctx = talloc_parent(src);
+ const unsigned a = desired_type->base_type;
+ const unsigned b = src->type->base_type;
+ ir_expression *result = NULL;
+
+ if (src->type->is_error())
+ return src;
+
+ assert(a <= GLSL_TYPE_BOOL);
+ assert(b <= GLSL_TYPE_BOOL);
+
+ if ((a == b) || (src->type->is_integer() && desired_type->is_integer()))
+ return src;
+
+ switch (a) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ if (b == GLSL_TYPE_FLOAT)
+ result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL);
+ else {
+ assert(b == GLSL_TYPE_BOOL);
+ result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL);
+ }
+ break;
+ case GLSL_TYPE_FLOAT:
+ switch (b) {
+ case GLSL_TYPE_UINT:
+ result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL);
+ break;
+ case GLSL_TYPE_INT:
+ result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL);
+ break;
+ case GLSL_TYPE_BOOL:
+ result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL);
+ break;
+ }
+ break;
+ case GLSL_TYPE_BOOL: {
+ ir_constant *zero = NULL;
+
+ switch (b) {
+ case GLSL_TYPE_UINT: zero = new(ctx) ir_constant(unsigned(0)); break;
+ case GLSL_TYPE_INT: zero = new(ctx) ir_constant(int(0)); break;
+ case GLSL_TYPE_FLOAT: zero = new(ctx) ir_constant(0.0f); break;
+ }
+
+ result = new(ctx) ir_expression(ir_binop_nequal, desired_type, src, zero);
+ }
+ }
+
+ assert(result != NULL);
+
+ ir_constant *const constant = result->constant_expression_value();
+ return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result;
+}
+
+
+/**
+ * Dereference a specific component from a scalar, vector, or matrix
+ */
+static ir_rvalue *
+dereference_component(ir_rvalue *src, unsigned component)
+{
+ void *ctx = talloc_parent(src);
+ assert(component < src->type->components());
+
+ /* If the source is a constant, just create a new constant instead of a
+ * dereference of the existing constant.
+ */
+ ir_constant *constant = src->as_constant();
+ if (constant)
+ return new(ctx) ir_constant(constant, component);
+
+ if (src->type->is_scalar()) {
+ return src;
+ } else if (src->type->is_vector()) {
+ return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1);
+ } else {
+ assert(src->type->is_matrix());
+
+ /* Dereference a row of the matrix, then call this function again to get
+ * a specific element from that row.
+ */
+ const int c = component / src->type->column_type()->vector_elements;
+ const int r = component % src->type->column_type()->vector_elements;
+ ir_constant *const col_index = new(ctx) ir_constant(c);
+ ir_dereference *const col = new(ctx) ir_dereference_array(src, col_index);
+
+ col->type = src->type->column_type();
+
+ return dereference_component(col, r);
+ }
+
+ assert(!"Should not get here.");
+ return NULL;
+}
+
+
+static ir_rvalue *
+process_array_constructor(exec_list *instructions,
+ const glsl_type *constructor_type,
+ YYLTYPE *loc, exec_list *parameters,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ /* Array constructors come in two forms: sized and unsized. Sized array
+ * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4
+ * variables. In this case the number of parameters must exactly match the
+ * specified size of the array.
+ *
+ * Unsized array constructors look like 'vec4[](a, b)', where 'a' and 'b'
+ * are vec4 variables. In this case the size of the array being constructed
+ * is determined by the number of parameters.
+ *
+ * From page 52 (page 58 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "There must be exactly the same number of arguments as the size of
+ * the array being constructed. If no size is present in the
+ * constructor, then the array is explicitly sized to the number of
+ * arguments provided. The arguments are assigned in order, starting at
+ * element 0, to the elements of the constructed array. Each argument
+ * must be the same type as the element type of the array, or be a type
+ * that can be converted to the element type of the array according to
+ * Section 4.1.10 "Implicit Conversions.""
+ */
+ exec_list actual_parameters;
+ const unsigned parameter_count =
+ process_parameters(instructions, &actual_parameters, parameters, state);
+
+ if ((parameter_count == 0)
+ || ((constructor_type->length != 0)
+ && (constructor_type->length != parameter_count))) {
+ const unsigned min_param = (constructor_type->length == 0)
+ ? 1 : constructor_type->length;
+
+ _mesa_glsl_error(loc, state, "array constructor must have %s %u "
+ "parameter%s",
+ (constructor_type->length != 0) ? "at least" : "exactly",
+ min_param, (min_param <= 1) ? "" : "s");
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ if (constructor_type->length == 0) {
+ constructor_type =
+ glsl_type::get_array_instance(state,
+ constructor_type->element_type(),
+ parameter_count);
+ assert(constructor_type != NULL);
+ assert(constructor_type->length == parameter_count);
+ }
+
+ ir_function *f = state->symbols->get_function(constructor_type->name);
+
+ /* If the constructor for this type of array does not exist, generate the
+ * prototype and add it to the symbol table.
+ */
+ if (f == NULL) {
+ f = constructor_type->generate_constructor(state->symbols);
+ }
+
+ ir_rvalue *const r =
+ process_call(instructions, f, loc, &actual_parameters, state);
+
+ assert(r != NULL);
+ assert(r->type->is_error() || (r->type == constructor_type));
+
+ return r;
+}
+
+
+/**
+ * Try to convert a record constructor to a constant expression
+ */
+static ir_constant *
+constant_record_constructor(const glsl_type *constructor_type,
+ YYLTYPE *loc, exec_list *parameters,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ bool all_parameters_are_constant = true;
+
+ exec_node *node = parameters->head;
+ for (unsigned i = 0; i < constructor_type->length; i++) {
+ ir_instruction *ir = (ir_instruction *) node;
+
+ if (node->is_tail_sentinal()) {
+ _mesa_glsl_error(loc, state,
+ "insufficient parameters to constructor for `%s'",
+ constructor_type->name);
+ return NULL;
+ }
+
+ if (ir->type != constructor_type->fields.structure[i].type) {
+ _mesa_glsl_error(loc, state,
+ "parameter type mismatch in constructor for `%s' "
+ " (%s vs %s)",
+ constructor_type->name,
+ ir->type->name,
+ constructor_type->fields.structure[i].type->name);
+ return NULL;
+ }
+
+ if (ir->as_constant() == NULL)
+ all_parameters_are_constant = false;
+
+ node = node->next;
+ }
+
+ if (!all_parameters_are_constant)
+ return NULL;
+
+ return new(ctx) ir_constant(constructor_type, parameters);
+}
+
+
+/**
+ * Generate data for a constant matrix constructor w/a single scalar parameter
+ *
+ * Matrix constructors in GLSL can be passed a single scalar of the
+ * approriate type. In these cases, the resulting matrix is the identity
+ * matrix multipled by the specified scalar. This function generates data for
+ * that matrix.
+ *
+ * \param type Type of the desired matrix.
+ * \param initializer Scalar value used to initialize the matrix diagonal.
+ * \param data Location to store the resulting matrix.
+ */
+void
+generate_constructor_matrix(const glsl_type *type, ir_constant *initializer,
+ ir_constant_data *data)
+{
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ for (unsigned i = 0; i < type->components(); i++)
+ data->u[i] = 0;
+
+ for (unsigned i = 0; i < type->matrix_columns; i++) {
+ /* The array offset of the ith row and column of the matrix.
+ */
+ const unsigned idx = (i * type->vector_elements) + i;
+
+ data->u[idx] = initializer->value.u[0];
+ }
+ break;
+
+ case GLSL_TYPE_FLOAT:
+ for (unsigned i = 0; i < type->components(); i++)
+ data->f[i] = 0;
+
+ for (unsigned i = 0; i < type->matrix_columns; i++) {
+ /* The array offset of the ith row and column of the matrix.
+ */
+ const unsigned idx = (i * type->vector_elements) + i;
+
+ data->f[idx] = initializer->value.f[0];
+ }
+
+ break;
+
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+}
+
+
+/**
+ * Generate data for a constant vector constructor w/a single scalar parameter
+ *
+ * Vector constructors in GLSL can be passed a single scalar of the
+ * approriate type. In these cases, the resulting vector contains the specified
+ * value in all components. This function generates data for that vector.
+ *
+ * \param type Type of the desired vector.
+ * \param initializer Scalar value used to initialize the vector.
+ * \param data Location to store the resulting vector data.
+ */
+void
+generate_constructor_vector(const glsl_type *type, ir_constant *initializer,
+ ir_constant_data *data)
+{
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ for (unsigned i = 0; i < type->components(); i++)
+ data->u[i] = initializer->value.u[0];
+
+ break;
+
+ case GLSL_TYPE_FLOAT:
+ for (unsigned i = 0; i < type->components(); i++)
+ data->f[i] = initializer->value.f[0];
+
+ break;
+
+ case GLSL_TYPE_BOOL:
+ for (unsigned i = 0; i < type->components(); i++)
+ data->b[i] = initializer->value.b[0];
+
+ break;
+
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+}
+
+
+ir_rvalue *
+ast_function_expression::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ /* There are three sorts of function calls.
+ *
+ * 1. contstructors - The first subexpression is an ast_type_specifier.
+ * 2. methods - Only the .length() method of array types.
+ * 3. functions - Calls to regular old functions.
+ *
+ * Method calls are actually detected when the ast_field_selection
+ * expression is handled.
+ */
+ if (is_constructor()) {
+ const ast_type_specifier *type = (ast_type_specifier *) subexpressions[0];
+ YYLTYPE loc = type->get_location();
+ const char *name;
+
+ const glsl_type *const constructor_type = type->glsl_type(& name, state);
+
+
+ /* Constructors for samplers are illegal.
+ */
+ if (constructor_type->is_sampler()) {
+ _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ if (constructor_type->is_array()) {
+ if (state->language_version <= 110) {
+ _mesa_glsl_error(& loc, state,
+ "array constructors forbidden in GLSL 1.10");
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ return process_array_constructor(instructions, constructor_type,
+ & loc, &this->expressions, state);
+ }
+
+ /* There are two kinds of constructor call. Constructors for built-in
+ * language types, such as mat4 and vec2, are free form. The only
+ * requirement is that the parameters must provide enough values of the
+ * correct scalar type. Constructors for arrays and structures must
+ * have the exact number of parameters with matching types in the
+ * correct order. These constructors follow essentially the same type
+ * matching rules as functions.
+ */
+ if (constructor_type->is_numeric() || constructor_type->is_boolean()) {
+ /* Constructing a numeric type has a couple steps. First all values
+ * passed to the constructor are broken into individual parameters
+ * and type converted to the base type of the thing being constructed.
+ *
+ * At that point we have some number of values that match the base
+ * type of the thing being constructed. Now the constructor can be
+ * treated like a function call. Each numeric type has a small set
+ * of constructor functions. The set of new parameters will either
+ * match one of those functions or the original constructor is
+ * invalid.
+ */
+ const glsl_type *const base_type = constructor_type->get_base_type();
+
+ /* Total number of components of the type being constructed.
+ */
+ const unsigned type_components = constructor_type->components();
+
+ /* Number of components from parameters that have actually been
+ * consumed. This is used to perform several kinds of error checking.
+ */
+ unsigned components_used = 0;
+
+ unsigned matrix_parameters = 0;
+ unsigned nonmatrix_parameters = 0;
+ exec_list actual_parameters;
+
+ bool all_parameters_are_constant = true;
+
+ /* This handles invalid constructor calls such as 'vec4 v = vec4();'
+ */
+ if (this->expressions.is_empty()) {
+ _mesa_glsl_error(& loc, state, "too few components to construct "
+ "`%s'",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ foreach_list (n, &this->expressions) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ir_rvalue *result =
+ ast->hir(instructions, state)->as_rvalue();
+ ir_variable *result_var = NULL;
+
+ /* Attempt to convert the parameter to a constant valued expression.
+ * After doing so, track whether or not all the parameters to the
+ * constructor are trivially constant valued expressions.
+ */
+ ir_rvalue *const constant =
+ result->constant_expression_value();
+
+ if (constant != NULL)
+ result = constant;
+ else
+ all_parameters_are_constant = false;
+
+ /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "It is an error to provide extra arguments beyond this
+ * last used argument."
+ */
+ if (components_used >= type_components) {
+ _mesa_glsl_error(& loc, state, "too many parameters to `%s' "
+ "constructor",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ if (!result->type->is_numeric() && !result->type->is_boolean()) {
+ _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
+ "non-numeric data type",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ /* Count the number of matrix and nonmatrix parameters. This
+ * is used below to enforce some of the constructor rules.
+ */
+ if (result->type->is_matrix())
+ matrix_parameters++;
+ else
+ nonmatrix_parameters++;
+
+ /* We can't use the same instruction node in the multiple
+ * swizzle dereferences that happen, so assign it to a
+ * variable and deref that. Plus it saves computation for
+ * complicated expressions and handles
+ * glsl-vs-constructor-call.shader_test.
+ */
+ if (result->type->components() >= 1 && !result->as_constant()) {
+ result_var = new(ctx) ir_variable(result->type,
+ "constructor_tmp");
+ ir_dereference_variable *lhs;
+
+ lhs = new(ctx) ir_dereference_variable(result_var);
+ instructions->push_tail(new(ctx) ir_assignment(lhs,
+ result, NULL));
+ }
+
+ /* Process each of the components of the parameter. Dereference
+ * each component individually, perform any type conversions, and
+ * add it to the parameter list for the constructor.
+ */
+ for (unsigned i = 0; i < result->type->components(); i++) {
+ if (components_used >= type_components)
+ break;
+
+ ir_rvalue *component;
+
+ if (result_var) {
+ ir_dereference *d = new(ctx) ir_dereference_variable(result_var);
+ component = dereference_component(d, i);
+ } else {
+ component = dereference_component(result, i);
+ }
+ component = convert_component(component, base_type);
+
+ /* All cases that could result in component->type being the
+ * error type should have already been caught above.
+ */
+ assert(component->type == base_type);
+
+ if (component->as_constant() == NULL)
+ all_parameters_are_constant = false;
+
+ /* Don't actually generate constructor calls for scalars.
+ * Instead, do the usual component selection and conversion,
+ * and return the single component.
+ */
+ if (constructor_type->is_scalar())
+ return component;
+
+ actual_parameters.push_tail(component);
+ components_used++;
+ }
+ }
+
+ /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "It is an error to construct matrices from other matrices. This
+ * is reserved for future use."
+ */
+ if ((state->language_version <= 110) && (matrix_parameters > 0)
+ && constructor_type->is_matrix()) {
+ _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
+ "matrix in GLSL 1.10",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "If a matrix argument is given to a matrix constructor, it is
+ * an error to have any other arguments."
+ */
+ if ((matrix_parameters > 0)
+ && ((matrix_parameters + nonmatrix_parameters) > 1)
+ && constructor_type->is_matrix()) {
+ _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
+ "matrix must be only parameter",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "In these cases, there must be enough components provided in the
+ * arguments to provide an initializer for every component in the
+ * constructed value."
+ */
+ if ((components_used < type_components) && (components_used != 1)) {
+ _mesa_glsl_error(& loc, state, "too few components to construct "
+ "`%s'",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ ir_function *f = state->symbols->get_function(constructor_type->name);
+ if (f == NULL) {
+ _mesa_glsl_error(& loc, state, "no constructor for type `%s'",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ const ir_function_signature *sig =
+ f->matching_signature(& actual_parameters);
+ if (sig != NULL) {
+ /* If all of the parameters are trivially constant, create a
+ * constant representing the complete collection of parameters.
+ */
+ if (all_parameters_are_constant) {
+ if (components_used >= type_components)
+ return new(ctx) ir_constant(sig->return_type,
+ & actual_parameters);
+
+ assert(sig->return_type->is_vector()
+ || sig->return_type->is_matrix());
+
+ /* Constructors with exactly one component are special for
+ * vectors and matrices. For vectors it causes all elements of
+ * the vector to be filled with the value. For matrices it
+ * causes the matrix to be filled with 0 and the diagonal to be
+ * filled with the value.
+ */
+ ir_constant_data data;
+ ir_constant *const initializer =
+ (ir_constant *) actual_parameters.head;
+ if (sig->return_type->is_matrix())
+ generate_constructor_matrix(sig->return_type, initializer,
+ &data);
+ else
+ generate_constructor_vector(sig->return_type, initializer,
+ &data);
+
+ return new(ctx) ir_constant(sig->return_type, &data);
+ } else
+ return new(ctx) ir_call(sig, & actual_parameters);
+ } else {
+ /* FINISHME: Log a better error message here. G++ will show the
+ * FINSIHME: types of the actual parameters and the set of
+ * FINSIHME: candidate functions. A different error should also be
+ * FINSIHME: logged when multiple functions match.
+ */
+ _mesa_glsl_error(& loc, state, "no matching constructor for `%s'",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+ }
+
+ return ir_call::get_error_instruction(ctx);
+ } else {
+ const ast_expression *id = subexpressions[0];
+ YYLTYPE loc = id->get_location();
+ exec_list actual_parameters;
+
+ process_parameters(instructions, &actual_parameters, &this->expressions,
+ state);
+
+ const glsl_type *const type =
+ state->symbols->get_type(id->primary_expression.identifier);
+
+ if ((type != NULL) && type->is_record()) {
+ ir_constant *constant =
+ constant_record_constructor(type, &loc, &actual_parameters, state);
+
+ if (constant != NULL)
+ return constant;
+ }
+
+ return match_function_by_name(instructions,
+ id->primary_expression.identifier, & loc,
+ &actual_parameters, state);
+ }
+
+ return ir_call::get_error_instruction(ctx);
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ast_to_hir.c
+ * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
+ *
+ * During the conversion to HIR, the majority of the symantic checking is
+ * preformed on the program. This includes:
+ *
+ * * Symbol table management
+ * * Type checking
+ * * Function binding
+ *
+ * The majority of this work could be done during parsing, and the parser could
+ * probably generate HIR directly. However, this results in frequent changes
+ * to the parser code. Since we do not assume that every system this complier
+ * is built on will have Flex and Bison installed, we have to store the code
+ * generated by these tools in our version control system. In other parts of
+ * the system we've seen problems where a parser was changed but the generated
+ * code was not committed, merge conflicts where created because two developers
+ * had slightly different versions of Bison installed, etc.
+ *
+ * I have also noticed that running Bison generated parsers in GDB is very
+ * irritating. When you get a segfault on '$$ = $1->foo', you can't very
+ * well 'print $1' in GDB.
+ *
+ * As a result, my preference is to put as little C code as possible in the
+ * parser (and lexer) sources.
+ */
+
+#include "main/imports.h"
+#include "glsl_symbol_table.h"
+#include "glsl_parser_extras.h"
+#include "ast.h"
+#include "glsl_types.h"
+#include "ir.h"
+
+void
+_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
+{
+ _mesa_glsl_initialize_variables(instructions, state);
+ _mesa_glsl_initialize_constructors(instructions, state);
+ _mesa_glsl_initialize_functions(instructions, state);
+
+ state->current_function = NULL;
+
+ foreach_list_typed (ast_node, ast, link, & state->translation_unit)
+ ast->hir(instructions, state);
+}
+
+
+/**
+ * If a conversion is available, convert one operand to a different type
+ *
+ * The \c from \c ir_rvalue is converted "in place".
+ *
+ * \param to Type that the operand it to be converted to
+ * \param from Operand that is being converted
+ * \param state GLSL compiler state
+ *
+ * \return
+ * If a conversion is possible (or unnecessary), \c true is returned.
+ * Otherwise \c false is returned.
+ */
+static bool
+apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ if (to->base_type == from->type->base_type)
+ return true;
+
+ /* This conversion was added in GLSL 1.20. If the compilation mode is
+ * GLSL 1.10, the conversion is skipped.
+ */
+ if (state->language_version < 120)
+ return false;
+
+ /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "There are no implicit array or structure conversions. For
+ * example, an array of int cannot be implicitly converted to an
+ * array of float. There are no implicit conversions between
+ * signed and unsigned integers."
+ */
+ /* FINISHME: The above comment is partially a lie. There is int/uint
+ * FINISHME: conversion for immediate constants.
+ */
+ if (!to->is_float() || !from->type->is_numeric())
+ return false;
+
+ switch (from->type->base_type) {
+ case GLSL_TYPE_INT:
+ from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
+ break;
+ case GLSL_TYPE_UINT:
+ from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
+ break;
+ case GLSL_TYPE_BOOL:
+ from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
+ break;
+ default:
+ assert(0);
+ }
+
+ return true;
+}
+
+
+static const struct glsl_type *
+arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+ bool multiply,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ const glsl_type *type_a = value_a->type;
+ const glsl_type *type_b = value_b->type;
+
+ /* From GLSL 1.50 spec, page 56:
+ *
+ * "The arithmetic binary operators add (+), subtract (-),
+ * multiply (*), and divide (/) operate on integer and
+ * floating-point scalars, vectors, and matrices."
+ */
+ if (!type_a->is_numeric() || !type_b->is_numeric()) {
+ _mesa_glsl_error(loc, state,
+ "Operands to arithmetic operators must be numeric");
+ return glsl_type::error_type;
+ }
+
+
+ /* "If one operand is floating-point based and the other is
+ * not, then the conversions from Section 4.1.10 "Implicit
+ * Conversions" are applied to the non-floating-point-based operand."
+ */
+ if (!apply_implicit_conversion(type_a, value_b, state)
+ && !apply_implicit_conversion(type_b, value_a, state)) {
+ _mesa_glsl_error(loc, state,
+ "Could not implicitly convert operands to "
+ "arithmetic operator");
+ return glsl_type::error_type;
+ }
+ type_a = value_a->type;
+ type_b = value_b->type;
+
+ /* "If the operands are integer types, they must both be signed or
+ * both be unsigned."
+ *
+ * From this rule and the preceeding conversion it can be inferred that
+ * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
+ * The is_numeric check above already filtered out the case where either
+ * type is not one of these, so now the base types need only be tested for
+ * equality.
+ */
+ if (type_a->base_type != type_b->base_type) {
+ _mesa_glsl_error(loc, state,
+ "base type mismatch for arithmetic operator");
+ return glsl_type::error_type;
+ }
+
+ /* "All arithmetic binary operators result in the same fundamental type
+ * (signed integer, unsigned integer, or floating-point) as the
+ * operands they operate on, after operand type conversion. After
+ * conversion, the following cases are valid
+ *
+ * * The two operands are scalars. In this case the operation is
+ * applied, resulting in a scalar."
+ */
+ if (type_a->is_scalar() && type_b->is_scalar())
+ return type_a;
+
+ /* "* One operand is a scalar, and the other is a vector or matrix.
+ * In this case, the scalar operation is applied independently to each
+ * component of the vector or matrix, resulting in the same size
+ * vector or matrix."
+ */
+ if (type_a->is_scalar()) {
+ if (!type_b->is_scalar())
+ return type_b;
+ } else if (type_b->is_scalar()) {
+ return type_a;
+ }
+
+ /* All of the combinations of <scalar, scalar>, <vector, scalar>,
+ * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
+ * handled.
+ */
+ assert(!type_a->is_scalar());
+ assert(!type_b->is_scalar());
+
+ /* "* The two operands are vectors of the same size. In this case, the
+ * operation is done component-wise resulting in the same size
+ * vector."
+ */
+ if (type_a->is_vector() && type_b->is_vector()) {
+ if (type_a == type_b) {
+ return type_a;
+ } else {
+ _mesa_glsl_error(loc, state,
+ "vector size mismatch for arithmetic operator");
+ return glsl_type::error_type;
+ }
+ }
+
+ /* All of the combinations of <scalar, scalar>, <vector, scalar>,
+ * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
+ * <vector, vector> have been handled. At least one of the operands must
+ * be matrix. Further, since there are no integer matrix types, the base
+ * type of both operands must be float.
+ */
+ assert(type_a->is_matrix() || type_b->is_matrix());
+ assert(type_a->base_type == GLSL_TYPE_FLOAT);
+ assert(type_b->base_type == GLSL_TYPE_FLOAT);
+
+ /* "* The operator is add (+), subtract (-), or divide (/), and the
+ * operands are matrices with the same number of rows and the same
+ * number of columns. In this case, the operation is done component-
+ * wise resulting in the same size matrix."
+ * * The operator is multiply (*), where both operands are matrices or
+ * one operand is a vector and the other a matrix. A right vector
+ * operand is treated as a column vector and a left vector operand as a
+ * row vector. In all these cases, it is required that the number of
+ * columns of the left operand is equal to the number of rows of the
+ * right operand. Then, the multiply (*) operation does a linear
+ * algebraic multiply, yielding an object that has the same number of
+ * rows as the left operand and the same number of columns as the right
+ * operand. Section 5.10 "Vector and Matrix Operations" explains in
+ * more detail how vectors and matrices are operated on."
+ */
+ if (! multiply) {
+ if (type_a == type_b)
+ return type_a;
+ } else {
+ if (type_a->is_matrix() && type_b->is_matrix()) {
+ /* Matrix multiply. The columns of A must match the rows of B. Given
+ * the other previously tested constraints, this means the vector type
+ * of a row from A must be the same as the vector type of a column from
+ * B.
+ */
+ if (type_a->row_type() == type_b->column_type()) {
+ /* The resulting matrix has the number of columns of matrix B and
+ * the number of rows of matrix A. We get the row count of A by
+ * looking at the size of a vector that makes up a column. The
+ * transpose (size of a row) is done for B.
+ */
+ const glsl_type *const type =
+ glsl_type::get_instance(type_a->base_type,
+ type_a->column_type()->vector_elements,
+ type_b->row_type()->vector_elements);
+ assert(type != glsl_type::error_type);
+
+ return type;
+ }
+ } else if (type_a->is_matrix()) {
+ /* A is a matrix and B is a column vector. Columns of A must match
+ * rows of B. Given the other previously tested constraints, this
+ * means the vector type of a row from A must be the same as the
+ * vector the type of B.
+ */
+ if (type_a->row_type() == type_b)
+ return type_b;
+ } else {
+ assert(type_b->is_matrix());
+
+ /* A is a row vector and B is a matrix. Columns of A must match rows
+ * of B. Given the other previously tested constraints, this means
+ * the type of A must be the same as the vector type of a column from
+ * B.
+ */
+ if (type_a == type_b->column_type())
+ return type_a;
+ }
+
+ _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
+ return glsl_type::error_type;
+ }
+
+
+ /* "All other cases are illegal."
+ */
+ _mesa_glsl_error(loc, state, "type mismatch");
+ return glsl_type::error_type;
+}
+
+
+static const struct glsl_type *
+unary_arithmetic_result_type(const struct glsl_type *type,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ /* From GLSL 1.50 spec, page 57:
+ *
+ * "The arithmetic unary operators negate (-), post- and pre-increment
+ * and decrement (-- and ++) operate on integer or floating-point
+ * values (including vectors and matrices). All unary operators work
+ * component-wise on their operands. These result with the same type
+ * they operated on."
+ */
+ if (!type->is_numeric()) {
+ _mesa_glsl_error(loc, state,
+ "Operands to arithmetic operators must be numeric");
+ return glsl_type::error_type;
+ }
+
+ return type;
+}
+
+
+static const struct glsl_type *
+modulus_result_type(const struct glsl_type *type_a,
+ const struct glsl_type *type_b,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ /* From GLSL 1.50 spec, page 56:
+ * "The operator modulus (%) operates on signed or unsigned integers or
+ * integer vectors. The operand types must both be signed or both be
+ * unsigned."
+ */
+ if (!type_a->is_integer() || !type_b->is_integer()
+ || (type_a->base_type != type_b->base_type)) {
+ _mesa_glsl_error(loc, state, "type mismatch");
+ return glsl_type::error_type;
+ }
+
+ /* "The operands cannot be vectors of differing size. If one operand is
+ * a scalar and the other vector, then the scalar is applied component-
+ * wise to the vector, resulting in the same type as the vector. If both
+ * are vectors of the same size, the result is computed component-wise."
+ */
+ if (type_a->is_vector()) {
+ if (!type_b->is_vector()
+ || (type_a->vector_elements == type_b->vector_elements))
+ return type_a;
+ } else
+ return type_b;
+
+ /* "The operator modulus (%) is not defined for any other data types
+ * (non-integer types)."
+ */
+ _mesa_glsl_error(loc, state, "type mismatch");
+ return glsl_type::error_type;
+}
+
+
+static const struct glsl_type *
+relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ const glsl_type *type_a = value_a->type;
+ const glsl_type *type_b = value_b->type;
+
+ /* From GLSL 1.50 spec, page 56:
+ * "The relational operators greater than (>), less than (<), greater
+ * than or equal (>=), and less than or equal (<=) operate only on
+ * scalar integer and scalar floating-point expressions."
+ */
+ if (!type_a->is_numeric()
+ || !type_b->is_numeric()
+ || !type_a->is_scalar()
+ || !type_b->is_scalar()) {
+ _mesa_glsl_error(loc, state,
+ "Operands to relational operators must be scalar and "
+ "numeric");
+ return glsl_type::error_type;
+ }
+
+ /* "Either the operands' types must match, or the conversions from
+ * Section 4.1.10 "Implicit Conversions" will be applied to the integer
+ * operand, after which the types must match."
+ */
+ if (!apply_implicit_conversion(type_a, value_b, state)
+ && !apply_implicit_conversion(type_b, value_a, state)) {
+ _mesa_glsl_error(loc, state,
+ "Could not implicitly convert operands to "
+ "relational operator");
+ return glsl_type::error_type;
+ }
+ type_a = value_a->type;
+ type_b = value_b->type;
+
+ if (type_a->base_type != type_b->base_type) {
+ _mesa_glsl_error(loc, state, "base type mismatch");
+ return glsl_type::error_type;
+ }
+
+ /* "The result is scalar Boolean."
+ */
+ return glsl_type::bool_type;
+}
+
+
+/**
+ * Validates that a value can be assigned to a location with a specified type
+ *
+ * Validates that \c rhs can be assigned to some location. If the types are
+ * not an exact match but an automatic conversion is possible, \c rhs will be
+ * converted.
+ *
+ * \return
+ * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
+ * Otherwise the actual RHS to be assigned will be returned. This may be
+ * \c rhs, or it may be \c rhs after some type conversion.
+ *
+ * \note
+ * In addition to being used for assignments, this function is used to
+ * type-check return values.
+ */
+ir_rvalue *
+validate_assignment(struct _mesa_glsl_parse_state *state,
+ const glsl_type *lhs_type, ir_rvalue *rhs)
+{
+ const glsl_type *rhs_type = rhs->type;
+
+ /* If there is already some error in the RHS, just return it. Anything
+ * else will lead to an avalanche of error message back to the user.
+ */
+ if (rhs_type->is_error())
+ return rhs;
+
+ /* If the types are identical, the assignment can trivially proceed.
+ */
+ if (rhs_type == lhs_type)
+ return rhs;
+
+ /* If the array element types are the same and the size of the LHS is zero,
+ * the assignment is okay.
+ *
+ * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
+ * is handled by ir_dereference::is_lvalue.
+ */
+ if (lhs_type->is_array() && rhs->type->is_array()
+ && (lhs_type->element_type() == rhs->type->element_type())
+ && (lhs_type->array_size() == 0)) {
+ return rhs;
+ }
+
+ /* Check for implicit conversion in GLSL 1.20 */
+ if (apply_implicit_conversion(lhs_type, rhs, state)) {
+ rhs_type = rhs->type;
+ if (rhs_type == lhs_type)
+ return rhs;
+ }
+
+ return NULL;
+}
+
+ir_rvalue *
+do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
+ ir_rvalue *lhs, ir_rvalue *rhs,
+ YYLTYPE lhs_loc)
+{
+ void *ctx = talloc_parent(state);
+ bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
+
+ if (!error_emitted) {
+ /* FINISHME: This does not handle 'foo.bar.a.b.c[5].d = 5' */
+ if (!lhs->is_lvalue()) {
+ _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
+ error_emitted = true;
+ }
+ }
+
+ ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs);
+ if (new_rhs == NULL) {
+ _mesa_glsl_error(& lhs_loc, state, "type mismatch");
+ } else {
+ rhs = new_rhs;
+
+ /* If the LHS array was not declared with a size, it takes it size from
+ * the RHS. If the LHS is an l-value and a whole array, it must be a
+ * dereference of a variable. Any other case would require that the LHS
+ * is either not an l-value or not a whole array.
+ */
+ if (lhs->type->array_size() == 0) {
+ ir_dereference *const d = lhs->as_dereference();
+
+ assert(d != NULL);
+
+ ir_variable *const var = d->variable_referenced();
+
+ assert(var != NULL);
+
+ if (var->max_array_access >= unsigned(rhs->type->array_size())) {
+ /* FINISHME: This should actually log the location of the RHS. */
+ _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
+ "previous access",
+ var->max_array_access);
+ }
+
+ var->type = glsl_type::get_array_instance(state,
+ lhs->type->element_type(),
+ rhs->type->array_size());
+ }
+ }
+
+ /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
+ * but not post_inc) need the converted assigned value as an rvalue
+ * to handle things like:
+ *
+ * i = j += 1;
+ *
+ * So we always just store the computed value being assigned to a
+ * temporary and return a deref of that temporary. If the rvalue
+ * ends up not being used, the temp will get copy-propagated out.
+ */
+ ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp");
+ ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
+ instructions->push_tail(var);
+ instructions->push_tail(new(ctx) ir_assignment(deref_var,
+ rhs,
+ NULL));
+ deref_var = new(ctx) ir_dereference_variable(var);
+
+ instructions->push_tail(new(ctx) ir_assignment(lhs,
+ deref_var,
+ NULL));
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+
+/**
+ * Generate a new temporary and add its declaration to the instruction stream
+ */
+static ir_variable *
+generate_temporary(const glsl_type *type, exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ char *name = (char *) malloc(sizeof(char) * 13);
+
+ snprintf(name, 13, "tmp_%08X", state->temp_index);
+ state->temp_index++;
+
+ ir_variable *const var = new(ctx) ir_variable(type, name);
+ instructions->push_tail(var);
+
+ return var;
+}
+
+
+static ir_rvalue *
+get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
+{
+ void *ctx = talloc_parent(lvalue);
+ ir_variable *var;
+
+ /* FINISHME: Give unique names to the temporaries. */
+ var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp");
+ var->mode = ir_var_auto;
+
+ instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+ lvalue, NULL));
+
+ /* Once we've created this temporary, mark it read only so it's no
+ * longer considered an lvalue.
+ */
+ var->read_only = true;
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+
+ir_rvalue *
+ast_node::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ (void) instructions;
+ (void) state;
+
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_expression::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ static const int operations[AST_NUM_OPERATORS] = {
+ -1, /* ast_assign doesn't convert to ir_expression. */
+ -1, /* ast_plus doesn't convert to ir_expression. */
+ ir_unop_neg,
+ ir_binop_add,
+ ir_binop_sub,
+ ir_binop_mul,
+ ir_binop_div,
+ ir_binop_mod,
+ ir_binop_lshift,
+ ir_binop_rshift,
+ ir_binop_less,
+ ir_binop_greater,
+ ir_binop_lequal,
+ ir_binop_gequal,
+ ir_binop_equal,
+ ir_binop_nequal,
+ ir_binop_bit_and,
+ ir_binop_bit_xor,
+ ir_binop_bit_or,
+ ir_unop_bit_not,
+ ir_binop_logic_and,
+ ir_binop_logic_xor,
+ ir_binop_logic_or,
+ ir_unop_logic_not,
+
+ /* Note: The following block of expression types actually convert
+ * to multiple IR instructions.
+ */
+ ir_binop_mul, /* ast_mul_assign */
+ ir_binop_div, /* ast_div_assign */
+ ir_binop_mod, /* ast_mod_assign */
+ ir_binop_add, /* ast_add_assign */
+ ir_binop_sub, /* ast_sub_assign */
+ ir_binop_lshift, /* ast_ls_assign */
+ ir_binop_rshift, /* ast_rs_assign */
+ ir_binop_bit_and, /* ast_and_assign */
+ ir_binop_bit_xor, /* ast_xor_assign */
+ ir_binop_bit_or, /* ast_or_assign */
+
+ -1, /* ast_conditional doesn't convert to ir_expression. */
+ ir_binop_add, /* ast_pre_inc. */
+ ir_binop_sub, /* ast_pre_dec. */
+ ir_binop_add, /* ast_post_inc. */
+ ir_binop_sub, /* ast_post_dec. */
+ -1, /* ast_field_selection doesn't conv to ir_expression. */
+ -1, /* ast_array_index doesn't convert to ir_expression. */
+ -1, /* ast_function_call doesn't conv to ir_expression. */
+ -1, /* ast_identifier doesn't convert to ir_expression. */
+ -1, /* ast_int_constant doesn't convert to ir_expression. */
+ -1, /* ast_uint_constant doesn't conv to ir_expression. */
+ -1, /* ast_float_constant doesn't conv to ir_expression. */
+ -1, /* ast_bool_constant doesn't conv to ir_expression. */
+ -1, /* ast_sequence doesn't convert to ir_expression. */
+ };
+ ir_rvalue *result = NULL;
+ ir_rvalue *op[2];
+ const struct glsl_type *type = glsl_type::error_type;
+ bool error_emitted = false;
+ YYLTYPE loc;
+
+ loc = this->get_location();
+
+ switch (this->oper) {
+ case ast_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ result = do_assignment(instructions, state, op[0], op[1],
+ this->subexpressions[0]->get_location());
+ error_emitted = result->type->is_error();
+ type = result->type;
+ break;
+ }
+
+ case ast_plus:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ error_emitted = op[0]->type->is_error();
+ if (type->is_error())
+ op[0]->type = type;
+
+ result = op[0];
+ break;
+
+ case ast_neg:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ type = unary_arithmetic_result_type(op[0]->type, state, & loc);
+
+ error_emitted = type->is_error();
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], NULL);
+ break;
+
+ case ast_add:
+ case ast_sub:
+ case ast_mul:
+ case ast_div:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = arithmetic_result_type(op[0], op[1],
+ (this->oper == ast_mul),
+ state, & loc);
+ error_emitted = type->is_error();
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ break;
+
+ case ast_mod:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
+
+ assert(operations[this->oper] == ir_binop_mod);
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = type->is_error();
+ break;
+
+ case ast_lshift:
+ case ast_rshift:
+ _mesa_glsl_error(& loc, state, "FINISHME: implement bit-shift operators");
+ error_emitted = true;
+ break;
+
+ case ast_less:
+ case ast_greater:
+ case ast_lequal:
+ case ast_gequal:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = relational_result_type(op[0], op[1], state, & loc);
+
+ /* The relational operators must either generate an error or result
+ * in a scalar boolean. See page 57 of the GLSL 1.50 spec.
+ */
+ assert(type->is_error()
+ || ((type->base_type == GLSL_TYPE_BOOL)
+ && type->is_scalar()));
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = type->is_error();
+ break;
+
+ case ast_nequal:
+ case ast_equal:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "The equality operators equal (==), and not equal (!=)
+ * operate on all types. They result in a scalar Boolean. If
+ * the operand types do not match, then there must be a
+ * conversion from Section 4.1.10 "Implicit Conversions"
+ * applied to one operand that can make them match, in which
+ * case this conversion is done."
+ */
+ if ((!apply_implicit_conversion(op[0]->type, op[1], state)
+ && !apply_implicit_conversion(op[1]->type, op[0], state))
+ || (op[0]->type != op[1]->type)) {
+ _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
+ "type", (this->oper == ast_equal) ? "==" : "!=");
+ error_emitted = true;
+ } else if ((state->language_version <= 110)
+ && (op[0]->type->is_array() || op[1]->type->is_array())) {
+ _mesa_glsl_error(& loc, state, "array comparisons forbidden in "
+ "GLSL 1.10");
+ error_emitted = true;
+ }
+
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], op[1]);
+ type = glsl_type::bool_type;
+
+ assert(result->type == glsl_type::bool_type);
+ break;
+
+ case ast_bit_and:
+ case ast_bit_xor:
+ case ast_bit_or:
+ case ast_bit_not:
+ _mesa_glsl_error(& loc, state, "FINISHME: implement bit-wise operators");
+ error_emitted = true;
+ break;
+
+ case ast_logic_and: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_constant *op0_const = op[0]->constant_expression_value();
+ if (op0_const) {
+ if (op0_const->value.b[0]) {
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+ result = op[1];
+ } else {
+ result = op0_const;
+ }
+ type = glsl_type::bool_type;
+ } else {
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
+ instructions->push_tail(stmt);
+
+ op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
+ instructions, state);
+
+ ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const then_assign =
+ new(ctx) ir_assignment(then_deref, op[1], NULL);
+ stmt->then_instructions.push_tail(then_assign);
+
+ ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const else_assign =
+ new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL);
+ stmt->else_instructions.push_tail(else_assign);
+
+ result = new(ctx) ir_dereference_variable(tmp);
+ type = tmp->type;
+ }
+ break;
+ }
+
+ case ast_logic_or: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_constant *op0_const = op[0]->constant_expression_value();
+ if (op0_const) {
+ if (op0_const->value.b[0]) {
+ result = op0_const;
+ } else {
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+ result = op[1];
+ }
+ type = glsl_type::bool_type;
+ } else {
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
+ instructions->push_tail(stmt);
+
+ ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
+ instructions, state);
+
+ op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state, "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const then_assign =
+ new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL);
+ stmt->then_instructions.push_tail(then_assign);
+
+ ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const else_assign =
+ new(ctx) ir_assignment(else_deref, op[1], NULL);
+ stmt->else_instructions.push_tail(else_assign);
+
+ result = new(ctx) ir_dereference_variable(tmp);
+ type = tmp->type;
+ }
+ break;
+ }
+
+ case ast_logic_xor:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], op[1]);
+ type = glsl_type::bool_type;
+ break;
+
+ case ast_logic_not:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "operand of `!' must be scalar boolean");
+ error_emitted = true;
+ }
+
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], NULL);
+ type = glsl_type::bool_type;
+ break;
+
+ case ast_mul_assign:
+ case ast_div_assign:
+ case ast_add_assign:
+ case ast_sub_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = arithmetic_result_type(op[0], op[1],
+ (this->oper == ast_mul_assign),
+ state, & loc);
+
+ ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+ type = result->type;
+ error_emitted = (op[0]->type->is_error());
+
+ /* GLSL 1.10 does not allow array assignment. However, we don't have to
+ * explicitly test for this because none of the binary expression
+ * operators allow array operands either.
+ */
+
+ break;
+ }
+
+ case ast_mod_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
+
+ assert(operations[this->oper] == ir_binop_mod);
+
+ struct ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+ type = result->type;
+ error_emitted = type->is_error();
+ break;
+ }
+
+ case ast_ls_assign:
+ case ast_rs_assign:
+ _mesa_glsl_error(& loc, state,
+ "FINISHME: implement bit-shift assignment operators");
+ error_emitted = true;
+ break;
+
+ case ast_and_assign:
+ case ast_xor_assign:
+ case ast_or_assign:
+ _mesa_glsl_error(& loc, state,
+ "FINISHME: implement logic assignment operators");
+ error_emitted = true;
+ break;
+
+ case ast_conditional: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "The ternary selection operator (?:). It operates on three
+ * expressions (exp1 ? exp2 : exp3). This operator evaluates the
+ * first expression, which must result in a scalar Boolean."
+ */
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state, "?: condition must be scalar boolean");
+ error_emitted = true;
+ }
+
+ /* The :? operator is implemented by generating an anonymous temporary
+ * followed by an if-statement. The last instruction in each branch of
+ * the if-statement assigns a value to the anonymous temporary. This
+ * temporary is the r-value of the expression.
+ */
+ exec_list then_instructions;
+ exec_list else_instructions;
+
+ op[1] = this->subexpressions[1]->hir(&then_instructions, state);
+ op[2] = this->subexpressions[2]->hir(&else_instructions, state);
+
+ /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "The second and third expressions can be any type, as
+ * long their types match, or there is a conversion in
+ * Section 4.1.10 "Implicit Conversions" that can be applied
+ * to one of the expressions to make their types match. This
+ * resulting matching type is the type of the entire
+ * expression."
+ */
+ if ((!apply_implicit_conversion(op[1]->type, op[2], state)
+ && !apply_implicit_conversion(op[2]->type, op[1], state))
+ || (op[1]->type != op[2]->type)) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
+ "operator must have matching types.");
+ error_emitted = true;
+ type = glsl_type::error_type;
+ } else {
+ type = op[1]->type;
+ }
+
+ ir_constant *cond_val = op[0]->constant_expression_value();
+ ir_constant *then_val = op[1]->constant_expression_value();
+ ir_constant *else_val = op[2]->constant_expression_value();
+
+ if (then_instructions.is_empty()
+ && else_instructions.is_empty()
+ && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
+ result = (cond_val->value.b[0]) ? then_val : else_val;
+ } else {
+ ir_variable *const tmp = generate_temporary(type,
+ instructions, state);
+
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
+ instructions->push_tail(stmt);
+
+ then_instructions.move_nodes_to(& stmt->then_instructions);
+ ir_dereference *const then_deref =
+ new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const then_assign =
+ new(ctx) ir_assignment(then_deref, op[1], NULL);
+ stmt->then_instructions.push_tail(then_assign);
+
+ else_instructions.move_nodes_to(& stmt->else_instructions);
+ ir_dereference *const else_deref =
+ new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const else_assign =
+ new(ctx) ir_assignment(else_deref, op[2], NULL);
+ stmt->else_instructions.push_tail(else_assign);
+
+ result = new(ctx) ir_dereference_variable(tmp);
+ }
+ break;
+ }
+
+ case ast_pre_inc:
+ case ast_pre_dec: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
+ op[1] = new(ctx) ir_constant(1.0f);
+ else
+ op[1] = new(ctx) ir_constant(1);
+
+ type = arithmetic_result_type(op[0], op[1], false, state, & loc);
+
+ struct ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+ type = result->type;
+ error_emitted = op[0]->type->is_error();
+ break;
+ }
+
+ case ast_post_inc:
+ case ast_post_dec: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
+ op[1] = new(ctx) ir_constant(1.0f);
+ else
+ op[1] = new(ctx) ir_constant(1);
+
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+
+ type = arithmetic_result_type(op[0], op[1], false, state, & loc);
+
+ struct ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ /* Get a temporary of a copy of the lvalue before it's modified.
+ * This may get thrown away later.
+ */
+ result = get_lvalue_copy(instructions, (ir_rvalue *)op[0]->clone(NULL));
+
+ (void)do_assignment(instructions, state,
+ (ir_rvalue *)op[0]->clone(NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+
+ type = result->type;
+ error_emitted = op[0]->type->is_error();
+ break;
+ }
+
+ case ast_field_selection:
+ result = _mesa_ast_field_selection_to_hir(this, instructions, state);
+ type = result->type;
+ break;
+
+ case ast_array_index: {
+ YYLTYPE index_loc = subexpressions[1]->get_location();
+
+ op[0] = subexpressions[0]->hir(instructions, state);
+ op[1] = subexpressions[1]->hir(instructions, state);
+
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+
+ ir_rvalue *const array = op[0];
+
+ result = new(ctx) ir_dereference_array(op[0], op[1]);
+
+ /* Do not use op[0] after this point. Use array.
+ */
+ op[0] = NULL;
+
+
+ if (error_emitted)
+ break;
+
+ if (!array->type->is_array()
+ && !array->type->is_matrix()
+ && !array->type->is_vector()) {
+ _mesa_glsl_error(& index_loc, state,
+ "cannot dereference non-array / non-matrix / "
+ "non-vector");
+ error_emitted = true;
+ }
+
+ if (!op[1]->type->is_integer()) {
+ _mesa_glsl_error(& index_loc, state,
+ "array index must be integer type");
+ error_emitted = true;
+ } else if (!op[1]->type->is_scalar()) {
+ _mesa_glsl_error(& index_loc, state,
+ "array index must be scalar");
+ error_emitted = true;
+ }
+
+ /* If the array index is a constant expression and the array has a
+ * declared size, ensure that the access is in-bounds. If the array
+ * index is not a constant expression, ensure that the array has a
+ * declared size.
+ */
+ ir_constant *const const_index = op[1]->constant_expression_value();
+ if (const_index != NULL) {
+ const int idx = const_index->value.i[0];
+ const char *type_name;
+ unsigned bound = 0;
+
+ if (array->type->is_matrix()) {
+ type_name = "matrix";
+ } else if (array->type->is_vector()) {
+ type_name = "vector";
+ } else {
+ type_name = "array";
+ }
+
+ /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "It is illegal to declare an array with a size, and then
+ * later (in the same shader) index the same array with an
+ * integral constant expression greater than or equal to the
+ * declared size. It is also illegal to index an array with a
+ * negative constant expression."
+ */
+ if (array->type->is_matrix()) {
+ if (array->type->row_type()->vector_elements <= idx) {
+ bound = array->type->row_type()->vector_elements;
+ }
+ } else if (array->type->is_vector()) {
+ if (array->type->vector_elements <= idx) {
+ bound = array->type->vector_elements;
+ }
+ } else {
+ if ((array->type->array_size() > 0)
+ && (array->type->array_size() <= idx)) {
+ bound = array->type->array_size();
+ }
+ }
+
+ if (bound > 0) {
+ _mesa_glsl_error(& loc, state, "%s index must be < %u",
+ type_name, bound);
+ error_emitted = true;
+ } else if (idx < 0) {
+ _mesa_glsl_error(& loc, state, "%s index must be >= 0",
+ type_name);
+ error_emitted = true;
+ }
+
+ if (array->type->is_array()) {
+ /* If the array is a variable dereference, it dereferences the
+ * whole array, by definition. Use this to get the variable.
+ *
+ * FINISHME: Should some methods for getting / setting / testing
+ * FINISHME: array access limits be added to ir_dereference?
+ */
+ ir_variable *const v = array->whole_variable_referenced();
+ if ((v != NULL) && (unsigned(idx) > v->max_array_access))
+ v->max_array_access = idx;
+ }
+ }
+
+ if (error_emitted)
+ result->type = glsl_type::error_type;
+
+ type = result->type;
+ break;
+ }
+
+ case ast_function_call:
+ /* Should *NEVER* get here. ast_function_call should always be handled
+ * by ast_function_expression::hir.
+ */
+ assert(0);
+ break;
+
+ case ast_identifier: {
+ /* ast_identifier can appear several places in a full abstract syntax
+ * tree. This particular use must be at location specified in the grammar
+ * as 'variable_identifier'.
+ */
+ ir_variable *var =
+ state->symbols->get_variable(this->primary_expression.identifier);
+
+ result = new(ctx) ir_dereference_variable(var);
+
+ if (var != NULL) {
+ type = result->type;
+ } else {
+ _mesa_glsl_error(& loc, state, "`%s' undeclared",
+ this->primary_expression.identifier);
+
+ error_emitted = true;
+ }
+ break;
+ }
+
+ case ast_int_constant:
+ type = glsl_type::int_type;
+ result = new(ctx) ir_constant(this->primary_expression.int_constant);
+ break;
+
+ case ast_uint_constant:
+ type = glsl_type::uint_type;
+ result = new(ctx) ir_constant(this->primary_expression.uint_constant);
+ break;
+
+ case ast_float_constant:
+ type = glsl_type::float_type;
+ result = new(ctx) ir_constant(this->primary_expression.float_constant);
+ break;
+
+ case ast_bool_constant:
+ type = glsl_type::bool_type;
+ result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
+ break;
+
+ case ast_sequence: {
+ /* It should not be possible to generate a sequence in the AST without
+ * any expressions in it.
+ */
+ assert(!this->expressions.is_empty());
+
+ /* The r-value of a sequence is the last expression in the sequence. If
+ * the other expressions in the sequence do not have side-effects (and
+ * therefore add instructions to the instruction list), they get dropped
+ * on the floor.
+ */
+ foreach_list_typed (ast_node, ast, link, &this->expressions)
+ result = ast->hir(instructions, state);
+
+ type = result->type;
+
+ /* Any errors should have already been emitted in the loop above.
+ */
+ error_emitted = true;
+ break;
+ }
+ }
+
+ if (type->is_error() && !error_emitted)
+ _mesa_glsl_error(& loc, state, "type mismatch");
+
+ return result;
+}
+
+
+ir_rvalue *
+ast_expression_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ /* It is possible to have expression statements that don't have an
+ * expression. This is the solitary semicolon:
+ *
+ * for (i = 0; i < 5; i++)
+ * ;
+ *
+ * In this case the expression will be NULL. Test for NULL and don't do
+ * anything in that case.
+ */
+ if (expression != NULL)
+ expression->hir(instructions, state);
+
+ /* Statements do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_compound_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (new_scope)
+ state->symbols->push_scope();
+
+ foreach_list_typed (ast_node, ast, link, &this->statements)
+ ast->hir(instructions, state);
+
+ if (new_scope)
+ state->symbols->pop_scope();
+
+ /* Compound statements do not have r-values.
+ */
+ return NULL;
+}
+
+
+static const glsl_type *
+process_array_type(const glsl_type *base, ast_node *array_size,
+ struct _mesa_glsl_parse_state *state)
+{
+ unsigned length = 0;
+
+ /* FINISHME: Reject delcarations of multidimensional arrays. */
+
+ if (array_size != NULL) {
+ exec_list dummy_instructions;
+ ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
+ YYLTYPE loc = array_size->get_location();
+
+ /* FINISHME: Verify that the grammar forbids side-effects in array
+ * FINISHME: sizes. i.e., 'vec4 [x = 12] data'
+ */
+ assert(dummy_instructions.is_empty());
+
+ if (ir != NULL) {
+ if (!ir->type->is_integer()) {
+ _mesa_glsl_error(& loc, state, "array size must be integer type");
+ } else if (!ir->type->is_scalar()) {
+ _mesa_glsl_error(& loc, state, "array size must be scalar type");
+ } else {
+ ir_constant *const size = ir->constant_expression_value();
+
+ if (size == NULL) {
+ _mesa_glsl_error(& loc, state, "array size must be a "
+ "constant valued expression");
+ } else if (size->value.i[0] <= 0) {
+ _mesa_glsl_error(& loc, state, "array size must be > 0");
+ } else {
+ assert(size->type == ir->type);
+ length = size->value.u[0];
+ }
+ }
+ }
+ }
+
+ return glsl_type::get_array_instance(state, base, length);
+}
+
+
+const glsl_type *
+ast_type_specifier::glsl_type(const char **name,
+ struct _mesa_glsl_parse_state *state) const
+{
+ const struct glsl_type *type;
+
+ if ((this->type_specifier == ast_struct) && (this->type_name == NULL)) {
+ /* FINISHME: Handle annonymous structures. */
+ type = NULL;
+ } else {
+ type = state->symbols->get_type(this->type_name);
+ *name = this->type_name;
+
+ if (this->is_array) {
+ type = process_array_type(type, this->array_size, state);
+ }
+ }
+
+ return type;
+}
+
+
+static void
+apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
+ struct ir_variable *var,
+ struct _mesa_glsl_parse_state *state,
+ YYLTYPE *loc)
+{
+ if (qual->invariant)
+ var->invariant = 1;
+
+ /* FINISHME: Mark 'in' variables at global scope as read-only. */
+ if (qual->constant || qual->attribute || qual->uniform
+ || (qual->varying && (state->target == fragment_shader)))
+ var->read_only = 1;
+
+ if (qual->centroid)
+ var->centroid = 1;
+
+ if (qual->attribute && state->target != vertex_shader) {
+ var->type = glsl_type::error_type;
+ _mesa_glsl_error(loc, state,
+ "`attribute' variables may not be declared in the "
+ "%s shader",
+ _mesa_glsl_shader_target_name(state->target));
+ }
+
+ /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "The varying qualifier can be used only with the data types
+ * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
+ * these."
+ */
+ if (qual->varying) {
+ const glsl_type *non_array_type;
+
+ if (var->type && var->type->is_array())
+ non_array_type = var->type->fields.array;
+ else
+ non_array_type = var->type;
+
+ if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) {
+ var->type = glsl_type::error_type;
+ _mesa_glsl_error(loc, state,
+ "varying variables must be of base type float");
+ }
+ }
+
+ if (qual->in && qual->out)
+ var->mode = ir_var_inout;
+ else if (qual->attribute || qual->in
+ || (qual->varying && (state->target == fragment_shader)))
+ var->mode = ir_var_in;
+ else if (qual->out || (qual->varying && (state->target == vertex_shader)))
+ var->mode = ir_var_out;
+ else if (qual->uniform)
+ var->mode = ir_var_uniform;
+ else
+ var->mode = ir_var_auto;
+
+ if (qual->uniform)
+ var->shader_in = true;
+
+ /* Any 'in' or 'inout' variables at global scope must be marked as being
+ * shader inputs. Likewise, any 'out' or 'inout' variables at global scope
+ * must be marked as being shader outputs.
+ */
+ if (state->current_function == NULL) {
+ switch (var->mode) {
+ case ir_var_in:
+ case ir_var_uniform:
+ var->shader_in = true;
+ break;
+ case ir_var_out:
+ var->shader_out = true;
+ break;
+ case ir_var_inout:
+ var->shader_in = true;
+ var->shader_out = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (qual->flat)
+ var->interpolation = ir_var_flat;
+ else if (qual->noperspective)
+ var->interpolation = ir_var_noperspective;
+ else
+ var->interpolation = ir_var_smooth;
+
+ if (var->type->is_array() && (state->language_version >= 120)) {
+ var->array_lvalue = true;
+ }
+}
+
+
+ir_rvalue *
+ast_declarator_list::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ const struct glsl_type *decl_type;
+ const char *type_name = NULL;
+ ir_rvalue *result = NULL;
+ YYLTYPE loc = this->get_location();
+
+ /* The type specifier may contain a structure definition. Process that
+ * before any of the variable declarations.
+ */
+ (void) this->type->specifier->hir(instructions, state);
+
+ /* FINISHME: Handle vertex shader "invariant" declarations that do not
+ * FINISHME: include a type. These re-declare built-in variables to be
+ * FINISHME: invariant.
+ */
+
+ decl_type = this->type->specifier->glsl_type(& type_name, state);
+ if (this->declarations.is_empty()) {
+ /* There are only two valid cases where the declaration list can be
+ * empty.
+ *
+ * 1. The declaration is setting the default precision of a built-in
+ * type (e.g., 'precision highp vec4;').
+ *
+ * 2. Adding 'invariant' to an existing vertex shader output.
+ */
+
+ if (this->type->qualifier.invariant) {
+ } else if (decl_type != NULL) {
+ } else {
+ _mesa_glsl_error(& loc, state, "incomplete declaration");
+ }
+ }
+
+ foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+ const struct glsl_type *var_type;
+ struct ir_variable *var;
+
+ /* FINISHME: Emit a warning if a variable declaration shadows a
+ * FINISHME: declaration at a higher scope.
+ */
+
+ if ((decl_type == NULL) || decl_type->is_void()) {
+ if (type_name != NULL) {
+ _mesa_glsl_error(& loc, state,
+ "invalid type `%s' in declaration of `%s'",
+ type_name, decl->identifier);
+ } else {
+ _mesa_glsl_error(& loc, state,
+ "invalid type in declaration of `%s'",
+ decl->identifier);
+ }
+ continue;
+ }
+
+ if (decl->is_array) {
+ var_type = process_array_type(decl_type, decl->array_size, state);
+ } else {
+ var_type = decl_type;
+ }
+
+ var = new(ctx) ir_variable(var_type, decl->identifier);
+
+ /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
+ *
+ * "Global variables can only use the qualifiers const,
+ * attribute, uni form, or varying. Only one may be
+ * specified.
+ *
+ * Local variables can only use the qualifier const."
+ *
+ * This is relaxed in GLSL 1.30.
+ */
+ if (state->language_version < 120) {
+ if (this->type->qualifier.out) {
+ _mesa_glsl_error(& loc, state,
+ "`out' qualifier in declaration of `%s' "
+ "only valid for function parameters in GLSL 1.10.",
+ decl->identifier);
+ }
+ if (this->type->qualifier.in) {
+ _mesa_glsl_error(& loc, state,
+ "`in' qualifier in declaration of `%s' "
+ "only valid for function parameters in GLSL 1.10.",
+ decl->identifier);
+ }
+ /* FINISHME: Test for other invalid qualifiers. */
+ }
+
+ apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
+ & loc);
+
+ /* Attempt to add the variable to the symbol table. If this fails, it
+ * means the variable has already been declared at this scope. Arrays
+ * fudge this rule a little bit.
+ *
+ * From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
+ *
+ * "It is legal to declare an array without a size and then
+ * later re-declare the same name as an array of the same
+ * type and specify a size."
+ */
+ if (state->symbols->name_declared_this_scope(decl->identifier)) {
+ ir_variable *const earlier =
+ state->symbols->get_variable(decl->identifier);
+
+ if ((earlier != NULL)
+ && (earlier->type->array_size() == 0)
+ && var->type->is_array()
+ && (var->type->element_type() == earlier->type->element_type())) {
+ /* FINISHME: This doesn't match the qualifiers on the two
+ * FINISHME: declarations. It's not 100% clear whether this is
+ * FINISHME: required or not.
+ */
+
+ if (var->type->array_size() <= (int)earlier->max_array_access) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "array size must be > %u due to "
+ "previous access",
+ earlier->max_array_access);
+ }
+
+ earlier->type = var->type;
+ delete var;
+ var = NULL;
+ } else {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "`%s' redeclared",
+ decl->identifier);
+ }
+
+ continue;
+ }
+
+ /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
+ *
+ * "Identifiers starting with "gl_" are reserved for use by
+ * OpenGL, and may not be declared in a shader as either a
+ * variable or a function."
+ */
+ if (strncmp(decl->identifier, "gl_", 3) == 0) {
+ /* FINISHME: This should only trigger if we're not redefining
+ * FINISHME: a builtin (to add a qualifier, for example).
+ */
+ _mesa_glsl_error(& loc, state,
+ "identifier `%s' uses reserved `gl_' prefix",
+ decl->identifier);
+ }
+
+ instructions->push_tail(var);
+
+ if (state->current_function != NULL) {
+ const char *mode = NULL;
+ const char *extra = "";
+
+ /* There is no need to check for 'inout' here because the parser will
+ * only allow that in function parameter lists.
+ */
+ if (this->type->qualifier.attribute) {
+ mode = "attribute";
+ } else if (this->type->qualifier.uniform) {
+ mode = "uniform";
+ } else if (this->type->qualifier.varying) {
+ mode = "varying";
+ } else if (this->type->qualifier.in) {
+ mode = "in";
+ extra = " or in function parameter list";
+ } else if (this->type->qualifier.out) {
+ mode = "out";
+ extra = " or in function parameter list";
+ }
+
+ if (mode) {
+ _mesa_glsl_error(& loc, state,
+ "%s variable `%s' must be declared at "
+ "global scope%s",
+ mode, var->name, extra);
+ }
+ } else if (var->mode == ir_var_in) {
+ if (state->target == vertex_shader) {
+ bool error_emitted = false;
+
+ /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "Vertex shader inputs can only be float, floating-point
+ * vectors, matrices, signed and unsigned integers and integer
+ * vectors. Vertex shader inputs can also form arrays of these
+ * types, but not structures."
+ *
+ * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
+ *
+ * "Vertex shader inputs can only be float, floating-point
+ * vectors, matrices, signed and unsigned integers and integer
+ * vectors. They cannot be arrays or structures."
+ *
+ * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "The attribute qualifier can be used only with float,
+ * floating-point vectors, and matrices. Attribute variables
+ * cannot be declared as arrays or structures."
+ */
+ const glsl_type *check_type = var->type->is_array()
+ ? var->type->fields.array : var->type;
+
+ switch (check_type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ break;
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ if (state->language_version > 120)
+ break;
+ /* FALLTHROUGH */
+ default:
+ _mesa_glsl_error(& loc, state,
+ "vertex shader input / attribute cannot have "
+ "type %s`%s'",
+ var->type->is_array() ? "array of " : "",
+ check_type->name);
+ error_emitted = true;
+ }
+
+ if (!error_emitted && (state->language_version <= 130)
+ && var->type->is_array()) {
+ _mesa_glsl_error(& loc, state,
+ "vertex shader input / attribute cannot have "
+ "array type");
+ error_emitted = true;
+ }
+ }
+ }
+
+ if (decl->initializer != NULL) {
+ YYLTYPE initializer_loc = decl->initializer->get_location();
+
+ /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "All uniform variables are read-only and are initialized either
+ * directly by an application via API commands, or indirectly by
+ * OpenGL."
+ */
+ if ((state->language_version <= 110)
+ && (var->mode == ir_var_uniform)) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "cannot initialize uniforms in GLSL 1.10");
+ }
+
+ if (var->type->is_sampler()) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "cannot initialize samplers");
+ }
+
+ if ((var->mode == ir_var_in) && (state->current_function == NULL)) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "cannot initialize %s shader input / %s",
+ _mesa_glsl_shader_target_name(state->target),
+ (state->target == vertex_shader)
+ ? "attribute" : "varying");
+ }
+
+ ir_dereference *const lhs = new(ctx) ir_dereference_variable(var);
+ ir_rvalue *rhs = decl->initializer->hir(instructions, state);
+
+ /* Calculate the constant value if this is a const or uniform
+ * declaration.
+ */
+ if (this->type->qualifier.constant || this->type->qualifier.uniform) {
+ ir_constant *constant_value = rhs->constant_expression_value();
+ if (!constant_value) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "initializer of %s variable `%s' must be a "
+ "constant expression",
+ (this->type->qualifier.constant)
+ ? "const" : "uniform",
+ decl->identifier);
+ } else {
+ rhs = constant_value;
+ var->constant_value = constant_value;
+ }
+ }
+
+ if (rhs && !rhs->type->is_error()) {
+ bool temp = var->read_only;
+ if (this->type->qualifier.constant)
+ var->read_only = false;
+
+ /* Never emit code to initialize a uniform.
+ */
+ if (!this->type->qualifier.uniform)
+ result = do_assignment(instructions, state, lhs, rhs,
+ this->get_location());
+ var->read_only = temp;
+ }
+ }
+
+ /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "It is an error to write to a const variable outside of
+ * its declaration, so they must be initialized when
+ * declared."
+ */
+ if (this->type->qualifier.constant && decl->initializer == NULL) {
+ _mesa_glsl_error(& loc, state,
+ "const declaration of `%s' must be initialized");
+ }
+
+ /* Add the vairable to the symbol table after processing the initializer.
+ * This differs from most C-like languages, but it follows the GLSL
+ * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50
+ * spec:
+ *
+ * "Within a declaration, the scope of a name starts immediately
+ * after the initializer if present or immediately after the name
+ * being declared if not."
+ */
+ const bool added_variable =
+ state->symbols->add_variable(decl->identifier, var);
+ assert(added_variable);
+ }
+
+
+ /* Generally, variable declarations do not have r-values. However,
+ * one is used for the declaration in
+ *
+ * while (bool b = some_condition()) {
+ * ...
+ * }
+ *
+ * so we return the rvalue from the last seen declaration here.
+ */
+ return result;
+}
+
+
+ir_rvalue *
+ast_parameter_declarator::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ const struct glsl_type *type;
+ const char *name = NULL;
+ YYLTYPE loc = this->get_location();
+
+ type = this->type->specifier->glsl_type(& name, state);
+
+ if (type == NULL) {
+ if (name != NULL) {
+ _mesa_glsl_error(& loc, state,
+ "invalid type `%s' in declaration of `%s'",
+ name, this->identifier);
+ } else {
+ _mesa_glsl_error(& loc, state,
+ "invalid type in declaration of `%s'",
+ this->identifier);
+ }
+
+ type = glsl_type::error_type;
+ }
+
+ /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "Functions that accept no input arguments need not use void in the
+ * argument list because prototypes (or definitions) are required and
+ * therefore there is no ambiguity when an empty argument list "( )" is
+ * declared. The idiom "(void)" as a parameter list is provided for
+ * convenience."
+ *
+ * Placing this check here prevents a void parameter being set up
+ * for a function, which avoids tripping up checks for main taking
+ * parameters and lookups of an unnamed symbol.
+ */
+ if (type->is_void()) {
+ if (this->identifier != NULL)
+ _mesa_glsl_error(& loc, state,
+ "named parameter cannot have type `void'");
+
+ is_void = true;
+ return NULL;
+ }
+
+ if (formal_parameter && (this->identifier == NULL)) {
+ _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
+ return NULL;
+ }
+
+ is_void = false;
+ ir_variable *var = new(ctx) ir_variable(type, this->identifier);
+
+ /* FINISHME: Handle array declarations. Note that this requires
+ * FINISHME: complete handling of constant expressions.
+ */
+
+ /* Apply any specified qualifiers to the parameter declaration. Note that
+ * for function parameters the default mode is 'in'.
+ */
+ apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);
+ if (var->mode == ir_var_auto)
+ var->mode = ir_var_in;
+
+ instructions->push_tail(var);
+
+ /* Parameter declarations do not have r-values.
+ */
+ return NULL;
+}
+
+
+void
+ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
+ bool formal,
+ exec_list *ir_parameters,
+ _mesa_glsl_parse_state *state)
+{
+ ast_parameter_declarator *void_param = NULL;
+ unsigned count = 0;
+
+ foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
+ param->formal_parameter = formal;
+ param->hir(ir_parameters, state);
+
+ if (param->is_void)
+ void_param = param;
+
+ count++;
+ }
+
+ if ((void_param != NULL) && (count > 1)) {
+ YYLTYPE loc = void_param->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`void' parameter must be only parameter");
+ }
+}
+
+
+ir_rvalue *
+ast_function::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ ir_function *f = NULL;
+ ir_function_signature *sig = NULL;
+ exec_list hir_parameters;
+
+
+ /* Convert the list of function parameters to HIR now so that they can be
+ * used below to compare this function's signature with previously seen
+ * signatures for functions with the same name.
+ */
+ ast_parameter_declarator::parameters_to_hir(& this->parameters,
+ is_definition,
+ & hir_parameters, state);
+
+ const char *return_type_name;
+ const glsl_type *return_type =
+ this->return_type->specifier->glsl_type(& return_type_name, state);
+
+ assert(return_type != NULL);
+
+ /* Verify that this function's signature either doesn't match a previously
+ * seen signature for a function with the same name, or, if a match is found,
+ * that the previously seen signature does not have an associated definition.
+ */
+ const char *const name = identifier;
+ f = state->symbols->get_function(name);
+ if (f != NULL) {
+ ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
+ if (sig != NULL) {
+ const char *badvar = sig->qualifiers_match(&hir_parameters);
+ if (badvar != NULL) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
+ "qualifiers don't match prototype", name, badvar);
+ }
+
+ if (sig->return_type != return_type) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
+ "match prototype", name);
+ }
+
+ if (is_definition && sig->is_defined) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
+ sig = NULL;
+ }
+ }
+ } else if (state->symbols->name_declared_this_scope(name)) {
+ /* This function name shadows a non-function use of the same name.
+ */
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "function name `%s' conflicts with "
+ "non-function", name);
+ sig = NULL;
+ } else {
+ f = new(ctx) ir_function(name);
+ state->symbols->add_function(f->name, f);
+
+ /* Emit the new function header */
+ instructions->push_tail(f);
+ }
+
+ /* Verify the return type of main() */
+ if (strcmp(name, "main") == 0) {
+ if (! return_type->is_void()) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "main() must return void");
+ }
+
+ if (!hir_parameters.is_empty()) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "main() must not take any parameters");
+ }
+ }
+
+ /* Finish storing the information about this new function in its signature.
+ */
+ if (sig == NULL) {
+ sig = new(ctx) ir_function_signature(return_type);
+ f->add_signature(sig);
+ }
+
+ sig->replace_parameters(&hir_parameters);
+ signature = sig;
+
+ /* Function declarations (prototypes) do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_function_definition::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ prototype->is_definition = true;
+ prototype->hir(instructions, state);
+
+ ir_function_signature *signature = prototype->signature;
+
+ assert(state->current_function == NULL);
+ state->current_function = signature;
+
+ /* Duplicate parameters declared in the prototype as concrete variables.
+ * Add these to the symbol table.
+ */
+ state->symbols->push_scope();
+ foreach_iter(exec_list_iterator, iter, signature->parameters) {
+ ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();
+
+ assert(var != NULL);
+
+ /* The only way a parameter would "exist" is if two parameters have
+ * the same name.
+ */
+ if (state->symbols->name_declared_this_scope(var->name)) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
+ } else {
+ state->symbols->add_variable(var->name, var);
+ }
+ }
+
+ /* Convert the body of the function to HIR. */
+ this->body->hir(&signature->body, state);
+ signature->is_defined = true;
+
+ state->symbols->pop_scope();
+
+ assert(state->current_function == signature);
+ state->current_function = NULL;
+
+ /* Function definitions do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_jump_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+
+ switch (mode) {
+ case ast_return: {
+ ir_return *inst;
+ assert(state->current_function);
+
+ if (opt_return_value) {
+ if (state->current_function->return_type->base_type ==
+ GLSL_TYPE_VOID) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`return` with a value, in function `%s' "
+ "returning void",
+ state->current_function->function_name());
+ }
+
+ ir_expression *const ret = (ir_expression *)
+ opt_return_value->hir(instructions, state);
+ assert(ret != NULL);
+
+ /* FINISHME: Make sure the type of the return value matches the return
+ * FINISHME: type of the enclosing function.
+ */
+
+ inst = new(ctx) ir_return(ret);
+ } else {
+ if (state->current_function->return_type->base_type !=
+ GLSL_TYPE_VOID) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`return' with no value, in function %s returning "
+ "non-void",
+ state->current_function->function_name());
+ }
+ inst = new(ctx) ir_return;
+ }
+
+ instructions->push_tail(inst);
+ break;
+ }
+
+ case ast_discard:
+ /* FINISHME: discard support */
+ if (state->target != fragment_shader) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`discard' may only appear in a fragment shader");
+ }
+ break;
+
+ case ast_break:
+ case ast_continue:
+ /* FINISHME: Handle switch-statements. They cannot contain 'continue',
+ * FINISHME: and they use a different IR instruction for 'break'.
+ */
+ /* FINISHME: Correctly handle the nesting. If a switch-statement is
+ * FINISHME: inside a loop, a 'continue' is valid and will bind to the
+ * FINISHME: loop.
+ */
+ if (state->loop_or_switch_nesting == NULL) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`%s' may only appear in a loop",
+ (mode == ast_break) ? "break" : "continue");
+ } else {
+ ir_loop *const loop = state->loop_or_switch_nesting->as_loop();
+
+ if (loop != NULL) {
+ ir_loop_jump *const jump =
+ new(ctx) ir_loop_jump((mode == ast_break)
+ ? ir_loop_jump::jump_break
+ : ir_loop_jump::jump_continue);
+ instructions->push_tail(jump);
+ }
+ }
+
+ break;
+ }
+
+ /* Jump instructions do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_selection_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+
+ ir_rvalue *const condition = this->condition->hir(instructions, state);
+
+ /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "Any expression whose type evaluates to a Boolean can be used as the
+ * conditional expression bool-expression. Vector types are not accepted
+ * as the expression to if."
+ *
+ * The checks are separated so that higher quality diagnostics can be
+ * generated for cases where both rules are violated.
+ */
+ if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
+ YYLTYPE loc = this->condition->get_location();
+
+ _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
+ "boolean");
+ }
+
+ ir_if *const stmt = new(ctx) ir_if(condition);
+
+ if (then_statement != NULL)
+ then_statement->hir(& stmt->then_instructions, state);
+
+ if (else_statement != NULL)
+ else_statement->hir(& stmt->else_instructions, state);
+
+ instructions->push_tail(stmt);
+
+ /* if-statements do not have r-values.
+ */
+ return NULL;
+}
+
+
+void
+ast_iteration_statement::condition_to_hir(ir_loop *stmt,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+
+ if (condition != NULL) {
+ ir_rvalue *const cond =
+ condition->hir(& stmt->body_instructions, state);
+
+ if ((cond == NULL)
+ || !cond->type->is_boolean() || !cond->type->is_scalar()) {
+ YYLTYPE loc = condition->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "loop condition must be scalar boolean");
+ } else {
+ /* As the first code in the loop body, generate a block that looks
+ * like 'if (!condition) break;' as the loop termination condition.
+ */
+ ir_rvalue *const not_cond =
+ new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
+ NULL);
+
+ ir_if *const if_stmt = new(ctx) ir_if(not_cond);
+
+ ir_jump *const break_stmt =
+ new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+
+ if_stmt->then_instructions.push_tail(break_stmt);
+ stmt->body_instructions.push_tail(if_stmt);
+ }
+ }
+}
+
+
+ir_rvalue *
+ast_iteration_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+
+ /* For-loops and while-loops start a new scope, but do-while loops do not.
+ */
+ if (mode != ast_do_while)
+ state->symbols->push_scope();
+
+ if (init_statement != NULL)
+ init_statement->hir(instructions, state);
+
+ ir_loop *const stmt = new(ctx) ir_loop();
+ instructions->push_tail(stmt);
+
+ /* Track the current loop and / or switch-statement nesting.
+ */
+ ir_instruction *const nesting = state->loop_or_switch_nesting;
+ state->loop_or_switch_nesting = stmt;
+
+ if (mode != ast_do_while)
+ condition_to_hir(stmt, state);
+
+ if (body != NULL)
+ body->hir(& stmt->body_instructions, state);
+
+ if (rest_expression != NULL)
+ rest_expression->hir(& stmt->body_instructions, state);
+
+ if (mode == ast_do_while)
+ condition_to_hir(stmt, state);
+
+ if (mode != ast_do_while)
+ state->symbols->pop_scope();
+
+ /* Restore previous nesting before returning.
+ */
+ state->loop_or_switch_nesting = nesting;
+
+ /* Loops do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_type_specifier::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (this->structure != NULL)
+ return this->structure->hir(instructions, state);
+
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_struct_specifier::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ unsigned decl_count = 0;
+
+ /* Make an initial pass over the list of structure fields to determine how
+ * many there are. Each element in this list is an ast_declarator_list.
+ * This means that we actually need to count the number of elements in the
+ * 'declarations' list in each of the elements.
+ */
+ foreach_list_typed (ast_declarator_list, decl_list, link,
+ &this->declarations) {
+ foreach_list_const (decl_ptr, & decl_list->declarations) {
+ decl_count++;
+ }
+ }
+
+
+ /* Allocate storage for the structure fields and process the field
+ * declarations. As the declarations are processed, try to also convert
+ * the types to HIR. This ensures that structure definitions embedded in
+ * other structure definitions are processed.
+ */
+ glsl_struct_field *const fields = (glsl_struct_field *)
+ malloc(sizeof(*fields) * decl_count);
+
+ unsigned i = 0;
+ foreach_list_typed (ast_declarator_list, decl_list, link,
+ &this->declarations) {
+ const char *type_name;
+
+ decl_list->type->specifier->hir(instructions, state);
+
+ const glsl_type *decl_type =
+ decl_list->type->specifier->glsl_type(& type_name, state);
+
+ foreach_list_typed (ast_declaration, decl, link,
+ &decl_list->declarations) {
+ const struct glsl_type *const field_type =
+ (decl->is_array)
+ ? process_array_type(decl_type, decl->array_size, state)
+ : decl_type;
+
+ fields[i].type = (field_type != NULL)
+ ? field_type : glsl_type::error_type;
+ fields[i].name = decl->identifier;
+ i++;
+ }
+ }
+
+ assert(i == decl_count);
+
+ const char *name;
+ if (this->name == NULL) {
+ static unsigned anon_count = 1;
+ char buf[32];
+
+ snprintf(buf, sizeof(buf), "#anon_struct_%04x", anon_count);
+ anon_count++;
+
+ name = strdup(buf);
+ } else {
+ name = this->name;
+ }
+
+ glsl_type *t = new(ctx) glsl_type(fields, decl_count, name);
+
+ YYLTYPE loc = this->get_location();
+ if (!state->symbols->add_type(name, t)) {
+ _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
+ } else {
+ /* This logic is a bit tricky. It is an error to declare a structure at
+ * global scope if there is also a function with the same name.
+ */
+ if ((state->current_function == NULL)
+ && (state->symbols->get_function(name) != NULL)) {
+ _mesa_glsl_error(& loc, state, "name `%s' previously defined", name);
+ } else {
+ t->generate_constructor(state->symbols);
+ }
+
+ const glsl_type **s = (const glsl_type **)
+ realloc(state->user_structures,
+ sizeof(state->user_structures[0]) *
+ (state->num_user_structures + 1));
+ if (s != NULL) {
+ s[state->num_user_structures] = t;
+ state->user_structures = s;
+ state->num_user_structures++;
+ }
+ }
+
+ /* Structure type definitions do not have r-values.
+ */
+ return NULL;
+}
--- /dev/null
+/*
+ * 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"
+#include "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];
+}
--- /dev/null
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
--- /dev/null
+/* DO NOT MODIFY - automatically generated by generate_builtins.pl */
+/*
+ * 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 <stdio.h>
+#include "glsl_parser_extras.h"
+#include "ir_reader.h"
+
+void
+read_builtins(_mesa_glsl_parse_state *st, exec_list *instructions,
+ const char **functions, unsigned count)
+{
+ if (st->error)
+ return;
+
+ for (unsigned i = 0; i < count; i++) {
+ _mesa_glsl_read_ir(st, instructions, functions[i]);
+
+ if (st->error) {
+ printf("error reading builtin: %.35s ...\n", functions[i]);
+ return;
+ }
+ }
+}
+
+/* 110 builtins */
+
+static const char *builtins_110_abs = {
+ "((function abs\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float abs (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 abs (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 abs (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 abs (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_all = {
+ "((function all\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 arg0))\n"
+ " ((return (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))\n"
+ "\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 arg0))\n"
+ " ((return (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))\n"
+ "\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 arg0))\n"
+ " ((return (expression bool && (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_any = {
+ "((function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 arg0))\n"
+ " ((return (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))\n"
+ "\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 arg0))\n"
+ " ((return (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))\n"
+ "\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 arg0))\n"
+ " ((return (expression bool || (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_asin = {
+ "((function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float *\n"
+ " (expression float -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression float sqrt\n"
+ " (expression float -\n"
+ " (constant float (1.0))\n"
+ " (expression float abs (var_ref x)))))\n"
+ " (expression float +\n"
+ " (constant float (1.5707288))\n"
+ " (expression float *\n"
+ " (expression float abs (var_ref x))\n"
+ " (expression float +\n"
+ " (constant float (-0.2121144))\n"
+ " (expression float *\n"
+ " (constant float (0.0742610))\n"
+ " (expression float abs (var_ref x))))))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 *\n"
+ " (expression float -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression vec2 sqrt\n"
+ " (expression vec2 -\n"
+ " (constant float (1.0))\n"
+ " (expression vec2 abs (var_ref x)))))\n"
+ " (expression vec2 +\n"
+ " (constant float (1.5707288))\n"
+ " (expression vec2 *\n"
+ " (expression vec2 abs (var_ref x))\n"
+ " (expression vec2 +\n"
+ " (constant float (-0.2121144))\n"
+ " (expression vec2 *\n"
+ " (constant float (0.0742610))\n"
+ " (expression vec2 abs (var_ref x))))))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 *\n"
+ " (expression vec3 -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression vec3 sqrt\n"
+ " (expression vec3 -\n"
+ " (constant float (1.0))\n"
+ " (expression vec3 abs (var_ref x)))))\n"
+ " (expression vec3 +\n"
+ " (constant float (1.5707288))\n"
+ " (expression vec3 *\n"
+ " (expression vec3 abs (var_ref x))\n"
+ " (expression vec3 +\n"
+ " (constant float (-0.2121144))\n"
+ " (expression vec3 *\n"
+ " (constant float (0.0742610))\n"
+ " (expression vec3 abs (var_ref x))))))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 *\n"
+ " (expression vec4 -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression vec4 sqrt\n"
+ " (expression vec4 -\n"
+ " (constant float (1.0))\n"
+ " (expression vec4 abs (var_ref x)))))\n"
+ " (expression vec4 +\n"
+ " (constant float (1.5707288))\n"
+ " (expression vec4 *\n"
+ " (expression vec4 abs (var_ref x))\n"
+ " (expression vec4 +\n"
+ " (constant float (-0.2121144))\n"
+ " (expression vec4 *\n"
+ " (constant float (0.0742610))\n"
+ " (expression vec4 abs (var_ref x))))))))))\n"
+ ")\n"
+ "\n"
+ " (function acos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float - (constant float (1.5707963))\n"
+ " (call asin ((var_ref x)))))))\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 - (constant float (1.5707963))\n"
+ " (call asin ((var_ref x)))))))\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 - (constant float (1.5707963))\n"
+ " (call asin ((var_ref x)))))))\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 - (constant float (1.5707963))\n"
+ " (call asin ((var_ref x)))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_atan = {
+ "((function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (call asin ((expression float *\n"
+ " (var_ref x)\n"
+ " (expression float rsq\n"
+ " (expression float +\n"
+ " (expression float *\n"
+ " (var_ref x)\n"
+ " (var_ref x))\n"
+ " (constant float (1.0))))))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y_over_x))\n"
+ " ((return (call asin ((expression vec2 *\n"
+ " (var_ref y_over_x)\n"
+ " (expression vec2 rsq\n"
+ " (expression vec2 +\n"
+ " (expression vec2 *\n"
+ " (var_ref y_over_x)\n"
+ " (var_ref y_over_x))\n"
+ " (constant float (1.0))))))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y_over_x))\n"
+ " ((return (call asin ((expression vec3 *\n"
+ " (var_ref y_over_x)\n"
+ " (expression vec3 rsq\n"
+ " (expression vec3 +\n"
+ " (expression vec3 *\n"
+ " (var_ref y_over_x)\n"
+ " (var_ref y_over_x))\n"
+ " (constant float (1.0))))))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y_over_x))\n"
+ " ((return (call asin ((expression vec4 *\n"
+ " (var_ref y_over_x)\n"
+ " (expression vec4 rsq\n"
+ " (expression vec4 +\n"
+ " (expression vec4 *\n"
+ " (var_ref y_over_x)\n"
+ " (var_ref y_over_x))\n"
+ " (constant float (1.0))))))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float x))\n"
+ " ((declare () float r)\n"
+ " (if (expression bool >\n"
+ " (expression float abs (var_ref x))\n"
+ " (constant float (.0001)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r) (call atan ((expression float /\n"
+ " (var_ref y)\n"
+ " (var_ref x)))))\n"
+ " (if (expression bool <\n"
+ " (var_ref x)\n"
+ " (constant float (0.0)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r)\n"
+ " (expression float +\n"
+ " (var_ref r)\n"
+ " (expression float *\n"
+ " (expression int sign (var_ref y))\n"
+ " (constant float (3.1415926))))))\n"
+ " ()))\n"
+ " ())\n"
+ " (return (var_ref r))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 r)\n"
+ " (if (expression bool >\n"
+ " (expression vec2 abs (var_ref x))\n"
+ " (constant float (.0001)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r) (call atan ((expression vec2 /\n"
+ " (var_ref y)\n"
+ " (var_ref x)))))\n"
+ " (if (expression bool <\n"
+ " (var_ref x)\n"
+ " (constant float (0.0)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r)\n"
+ " (expression vec2 +\n"
+ " (var_ref r)\n"
+ " (expression vec2 *\n"
+ " (expression int sign (var_ref y))\n"
+ " (constant float (3.1415926))))))\n"
+ " ()))\n"
+ " ())\n"
+ " (return (var_ref r))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 x))\n"
+ " ((declare () vec3 r)\n"
+ " (if (expression bool >\n"
+ " (expression vec3 abs (var_ref x))\n"
+ " (constant float (.0001)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r) (call atan ((expression vec3 /\n"
+ " (var_ref y)\n"
+ " (var_ref x)))))\n"
+ " (if (expression bool <\n"
+ " (var_ref x)\n"
+ " (constant float (0.0)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r)\n"
+ " (expression vec3 +\n"
+ " (var_ref r)\n"
+ " (expression vec3 *\n"
+ " (expression int sign (var_ref y))\n"
+ " (constant float (3.1415926))))))\n"
+ " ()))\n"
+ " ())\n"
+ " (return (var_ref r))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 x))\n"
+ " ((declare () vec4 r)\n"
+ " (if (expression bool >\n"
+ " (expression vec4 abs (var_ref x))\n"
+ " (constant float (.0001)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r) (call atan ((expression vec4 /\n"
+ " (var_ref y)\n"
+ " (var_ref x)))))\n"
+ " (if (expression bool <\n"
+ " (var_ref x)\n"
+ " (constant float (0.0)))\n"
+ " ((assign (constant bool (1))\n"
+ " (var_ref r)\n"
+ " (expression vec4 +\n"
+ " (var_ref r)\n"
+ " (expression vec4 *\n"
+ " (expression int sign (var_ref y))\n"
+ " (constant float (3.1415926))))))\n"
+ " ()))\n"
+ " ())\n"
+ " (return (var_ref r))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_110_ceil = {
+ "((function ceil\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float ceil (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 ceil (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 ceil (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 ceil (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_clamp = {
+ "((function clamp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0)\n"
+ " (declare (in) float arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((return (expression float max (expression float min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1)\n"
+ " (declare (in) vec2 arg2))\n"
+ " ((return (expression vec2 max (expression vec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1)\n"
+ " (declare (in) vec3 arg2))\n"
+ " ((return (expression vec3 max (expression vec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1)\n"
+ " (declare (in) vec4 arg2))\n"
+ " ((return (expression vec4 max (expression vec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) float arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((declare () vec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) float arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((declare () vec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) float arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((declare () vec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result)) (expression vec4 max (expression vec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_cos = {
+ "((function cos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ((return (expression float cos (var_ref angle)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ((return (expression vec2 cos (var_ref angle)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ((return (expression vec3 cos (var_ref angle)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ((return (expression vec4 cos (var_ref angle)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_cross = {
+ "((function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((declare () vec3 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t))\n"
+ " (expression float - (expression float * (swiz y (var_ref arg0)) (swiz z (var_ref arg1)))\n"
+ " (expression float * (swiz y (var_ref arg1)) (swiz z (var_ref arg0)))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t))\n"
+ " (expression float - (expression float * (swiz z (var_ref arg0)) (swiz x (var_ref arg1)))\n"
+ " (expression float * (swiz z (var_ref arg1)) (swiz x (var_ref arg0)))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t))\n"
+ " (expression float - (expression float * (swiz x (var_ref arg0)) (swiz y (var_ref arg1)))\n"
+ " (expression float * (swiz x (var_ref arg1)) (swiz y (var_ref arg0)))))\n"
+ " (return (var_ref t))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_degrees = {
+ "((function degrees\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float * (var_ref arg0) (constant float (57.295780))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 * (var_ref arg0) (constant float (57.295780))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 * (var_ref arg0) (constant float (57.295780))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 * (var_ref arg0) (constant float (57.295780))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_distance = {
+ "((function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ((declare () float p)\n"
+ " (assign (constant bool (1)) (var_ref p) (expression float - (var_ref p0) (var_ref p1)))\n"
+ " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 p0)\n"
+ " (declare (in) vec2 p1))\n"
+ " ((declare () vec2 p)\n"
+ " (assign (constant bool (1)) (var_ref p) (expression vec2 - (var_ref p0) (var_ref p1)))\n"
+ " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 p0)\n"
+ " (declare (in) vec3 p1))\n"
+ " ((declare () vec3 p)\n"
+ " (assign (constant bool (1)) (var_ref p) (expression vec3 - (var_ref p0) (var_ref p1)))\n"
+ " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 p0)\n"
+ " (declare (in) vec4 p1))\n"
+ " ((declare () vec4 p)\n"
+ " (assign (constant bool (1)) (var_ref p) (expression vec4 - (var_ref p0) (var_ref p1)))\n"
+ " (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_dot = {
+ "((function dot\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression float dot (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_equal = {
+ "((function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_exp = {
+ "((function exp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float exp (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 exp (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 exp (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 exp (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_exp2 = {
+ "((function exp2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float exp2 (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 exp2 (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 exp2 (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 exp2 (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_faceforward = {
+ "((function faceforward\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float Nref))\n"
+ " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
+ " ((return (var_ref N)))\n"
+ " ((return (expression float neg (var_ref N)))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 Nref))\n"
+ " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
+ " ((return (var_ref N)))\n"
+ " ((return (expression vec2 neg (var_ref N)))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 Nref))\n"
+ " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
+ " ((return (var_ref N)))\n"
+ " ((return (expression vec3 neg (var_ref N)))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 Nref))\n"
+ " ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))\n"
+ " ((return (var_ref N)))\n"
+ " ((return (expression vec4 neg (var_ref N)))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_floor = {
+ "((function floor\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float floor (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 floor (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 floor (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 floor (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_fract = {
+ "((function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float - (var_ref x) (expression float floor (var_ref x))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((declare () vec3 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((declare () vec4 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float - (swiz w (var_ref x)) (expression float floor (swiz w (var_ref x)))))\n"
+ " (return (var_ref t))))\n"
+ "))\n"
+ "\n"
+};
+
+static const char *builtins_110_greaterThan = {
+ "((function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_greaterThanEqual = {
+ "((function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_inversesqrt = {
+ "((function inversesqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float rsq (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 rsq (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 rsq (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 rsq (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_length = {
+ "((function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_lessThan = {
+ "((function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_lessThanEqual = {
+ "((function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_log = {
+ "((function log\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float log (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 log (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 log (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 log (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_log2 = {
+ "((function log2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float log2 (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 log2 (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 log2 (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 log2 (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_matrixCompMult = {
+ "((function matrixCompMult\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 x)\n"
+ " (declare (in) mat2 y))\n"
+ " ((declare () mat2 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ "(return (var_ref z))))\n"
+ "\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 x)\n"
+ " (declare (in) mat3 y))\n"
+ " ((declare () mat3 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
+ "(return (var_ref z))))\n"
+ "\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 x)\n"
+ " (declare (in) mat4 y))\n"
+ " ((declare () mat4 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec4 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3))))) \n"
+ "(return (var_ref z))))\n"
+ "))\n"
+ "\n"
+};
+
+static const char *builtins_110_max = {
+ "((function max\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((return (expression float max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression vec2 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression vec3 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression vec4 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result))\n"
+ " (expression float max (swiz w (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_min = {
+ "((function min\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((return (expression float min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression vec2 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression vec3 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression vec4 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result))\n"
+ " (expression float min (swiz w (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_mix = {
+ "((function mix\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0)\n"
+ " (declare (in) float arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((return (expression float + (expression float * (var_ref arg0) (expression float - (constant float (1.000000)) (var_ref arg2))) (expression float * (var_ref arg1) (var_ref arg2))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1)\n"
+ " (declare (in) vec2 arg2))\n"
+ " ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1)\n"
+ " (declare (in) vec3 arg2))\n"
+ " ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1)\n"
+ " (declare (in) vec4 arg2))\n"
+ " ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_mod = {
+ "((function mod\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((return (expression float % (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression vec2 % (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression vec3 % (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression vec4 % (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((declare () vec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result))\n"
+ " (expression float % (swiz w (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_noise_fake = {
+ "((function noise1\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (constant float (0)))))\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (constant float (0)))))\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (constant float (0)))))\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (constant float (0)))))\n"
+ " )\n"
+ "\n"
+ " (function noise2\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (constant vec2 (0 0)))))\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (constant vec2 (0 0)))))\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (constant vec2 (0 0)))))\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (constant vec2 (0 0)))))\n"
+ " )\n"
+ "\n"
+ " (function noise3\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (constant vec3 (0 0 0)))))\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (constant vec3 (0 0 0)))))\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (constant vec3 (0 0 0)))))\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (constant vec3 (0 0 0)))))\n"
+ " )\n"
+ "\n"
+ " (function noise4\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (constant vec4 (0 0 0 0)))))\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (constant vec4 (0 0 0 0)))))\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (constant vec4 (0 0 0 0)))))\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (constant vec4 (0 0 0 0)))))\n"
+ " )\n"
+ ")\n"
+};
+
+static const char *builtins_110_normalize = {
+ "((function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_not = {
+ "((function not\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 arg0))\n"
+ " ((return (expression bvec2 ! (var_ref arg0)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 arg0))\n"
+ " ((return (expression bvec3 ! (var_ref arg0)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 arg0))\n"
+ " ((return (expression bvec4 ! (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_notEqual = {
+ "((function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression float != (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression int != (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_pow = {
+ "((function pow\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0)\n"
+ " (declare (in) float arg1))\n"
+ " ((return (expression float pow (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression vec2 pow (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression vec3 pow (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression vec4 pow (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_radians = {
+ "((function radians\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float * (var_ref arg0) (constant float (0.017453))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 * (var_ref arg0) (constant float (0.017453))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 * (var_ref arg0) (constant float (0.017453))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 * (var_ref arg0) (constant float (0.017453))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_reflect = {
+ "((function reflect\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float i)\n"
+ " (declare (in) float n))\n"
+ " ((return (expression float -\n"
+ " (var_ref i)\n"
+ " (expression float *\n"
+ " (constant float (2.0))\n"
+ " (expression float *\n"
+ " (expression float dot\n"
+ " (var_ref n)\n"
+ " (var_ref i))\n"
+ " (var_ref n)))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 i)\n"
+ " (declare (in) vec2 n))\n"
+ " ((return (expression vec2 -\n"
+ " (var_ref i)\n"
+ " (expression vec2 *\n"
+ " (constant float (2.0))\n"
+ " (expression vec2 *\n"
+ " (expression float dot\n"
+ " (var_ref n)\n"
+ " (var_ref i))\n"
+ " (var_ref n)))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 i)\n"
+ " (declare (in) vec3 n))\n"
+ " ((return (expression vec3 -\n"
+ " (var_ref i)\n"
+ " (expression vec3 *\n"
+ " (constant float (2.0))\n"
+ " (expression vec3 *\n"
+ " (expression float dot\n"
+ " (var_ref n)\n"
+ " (var_ref i))\n"
+ " (var_ref n)))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 i)\n"
+ " (declare (in) vec4 n))\n"
+ " ((return (expression vec4 -\n"
+ " (var_ref i)\n"
+ " (expression vec4 *\n"
+ " (constant float (2.0))\n"
+ " (expression vec4 *\n"
+ " (expression float dot\n"
+ " (var_ref n)\n"
+ " (var_ref i))\n"
+ " (var_ref n)))))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_110_refract = {
+ "((function refract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float i)\n"
+ " (declare (in) float n)\n"
+ " (declare (in) float eta))\n"
+ " ((declare () float k)\n"
+ " (assign (constant bool (1)) (var_ref k)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * \n"
+ " (expression float dot (var_ref n) (var_ref i))\n"
+ " (expression float dot (var_ref n) (var_ref i))))))))\n"
+ " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+ " ((return (constant float (0.0))))\n"
+ " ((return (expression float -\n"
+ " (expression float * (var_ref eta) (var_ref i))\n"
+ " (expression float *\n"
+ " (expression float +\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float dot (var_ref n) (var_ref i)))\n"
+ " (expression float sqrt (var_ref k)))\n"
+ " (var_ref n))))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 i)\n"
+ " (declare (in) vec2 n)\n"
+ " (declare (in) float eta))\n"
+ " ((declare () float k)\n"
+ " (assign (constant bool (1)) (var_ref k)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * \n"
+ " (expression float dot (var_ref n) (var_ref i))\n"
+ " (expression float dot (var_ref n) (var_ref i))))))))\n"
+ " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+ " ((return (constant vec2 (0.0 0.0))))\n"
+ " ((return (expression vec2 -\n"
+ " (expression vec2 * (var_ref eta) (var_ref i))\n"
+ " (expression vec2 *\n"
+ " (expression float +\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float dot (var_ref n) (var_ref i)))\n"
+ " (expression float sqrt (var_ref k)))\n"
+ " (var_ref n))))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 i)\n"
+ " (declare (in) vec3 n)\n"
+ " (declare (in) float eta))\n"
+ " ((declare () float k)\n"
+ " (assign (constant bool (1)) (var_ref k)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * \n"
+ " (expression float dot (var_ref n) (var_ref i))\n"
+ " (expression float dot (var_ref n) (var_ref i))))))))\n"
+ " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+ " ((return (constant vec3 (0.0 0.0))))\n"
+ " ((return (expression vec3 -\n"
+ " (expression vec3 * (var_ref eta) (var_ref i))\n"
+ " (expression vec3 *\n"
+ " (expression float +\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float dot (var_ref n) (var_ref i)))\n"
+ " (expression float sqrt (var_ref k)))\n"
+ " (var_ref n))))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 i)\n"
+ " (declare (in) vec4 n)\n"
+ " (declare (in) float eta))\n"
+ " ((declare () float k)\n"
+ " (assign (constant bool (1)) (var_ref k)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float - (constant float (1.0))\n"
+ " (expression float * \n"
+ " (expression float dot (var_ref n) (var_ref i))\n"
+ " (expression float dot (var_ref n) (var_ref i))))))))\n"
+ " (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+ " ((return (constant vec4 (0.0 0.0))))\n"
+ " ((return (expression vec4 -\n"
+ " (expression vec4 * (var_ref eta) (var_ref i))\n"
+ " (expression vec4 *\n"
+ " (expression float +\n"
+ " (expression float * (var_ref eta)\n"
+ " (expression float dot (var_ref n) (var_ref i)))\n"
+ " (expression float sqrt (var_ref k)))\n"
+ " (var_ref n))))))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_110_sign = {
+ "((function sign\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float sign (var_ref x)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((declare () vec3 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((declare () vec4 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float sign (swiz w (var_ref x))))\n"
+ " (return (var_ref t))))\n"
+ "))\n"
+ "\n"
+};
+
+static const char *builtins_110_sin = {
+ "((function sin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ((return (expression float sin (var_ref angle)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ((return (expression vec2 sin (var_ref angle)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ((return (expression vec3 sin (var_ref angle)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ((return (expression vec4 sin (var_ref angle)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_smoothstep = {
+ "((function smoothstep\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) float x))\n"
+ " ((declare () float t)\n"
+ "\n"
+ " (assign (constant bool (1)) (var_ref t)\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (var_ref x) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (return (expression float * (var_ref t) (expression float * (var_ref t) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (var_ref t))))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 t)\n"
+ " (declare () vec2 retval)\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
+ " (return (var_ref retval))\n"
+ " ))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ((declare () vec3 t)\n"
+ " (declare () vec3 retval)\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
+ " (return (var_ref retval))\n"
+ " ))\n"
+ "\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ((declare () vec4 t)\n"
+ " (declare () vec4 retval)\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz w (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz w (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))\n"
+ " (return (var_ref retval))\n"
+ " ))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge0)\n"
+ " (declare (in) vec2 edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 t)\n"
+ " (declare () vec2 retval)\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
+ " (return (var_ref retval))\n"
+ " ))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge0)\n"
+ " (declare (in) vec3 edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ((declare () vec3 t)\n"
+ " (declare () vec3 retval)\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
+ " (return (var_ref retval))\n"
+ " ))\n"
+ "\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge0)\n"
+ " (declare (in) vec4 edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ((declare () vec4 t)\n"
+ " (declare () vec4 retval)\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))\n"
+ "\n"
+ " (assign (constant bool (1)) (swiz w (var_ref t))\n"
+ " (expression float max\n"
+ " (expression float min\n"
+ " (expression float / (expression float - (swiz w (var_ref x)) (swiz w (var_ref edge0))) (expression float - (swiz w (var_ref edge1)) (swiz w (var_ref edge0))))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))\n"
+ " (return (var_ref retval))\n"
+ " ))\n"
+ "\n"
+ "))\n"
+ "\n"
+};
+
+static const char *builtins_110_sqrt = {
+ "((function sqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float sqrt (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 sqrt (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 sqrt (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 sqrt (var_ref arg0)))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_step = {
+ "((function step\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float b2f (expression bool < (var_ref x) (var_ref edge))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ((declare () vec3 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ((declare () vec4 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(var_ref edge))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ((declare () vec3 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(swiz z (var_ref edge)))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ((declare () vec4 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz z (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(swiz w (var_ref edge)))))\n"
+ " (return (var_ref t))))\n"
+ "))\n"
+ "\n"
+};
+
+static const char *builtins_110_tan = {
+ "((function tan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ((return (expression float / (expression float sin (var_ref angle)) (expression float cos (var_ref angle))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ((return (expression float / (expression float sin (var_ref angle)) (expression vec2 cos (var_ref angle))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ((return (expression float / (expression float sin (var_ref angle)) (expression vec3 cos (var_ref angle))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ((return (expression float / (expression float sin (var_ref angle)) (expression vec4 cos (var_ref angle))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_textures = {
+ "((function texture1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ ")\n"
+ " (function texture1DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ ")\n"
+ " (function texture1DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ ")\n"
+ "(function texture2DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture3D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ ")\n"
+ " (function texture3DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture3DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ ")\n"
+ " (function texture3DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ ")\n"
+ " (function textureCubeLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *functions_for_110 [] = {
+ builtins_110_abs,
+ builtins_110_all,
+ builtins_110_any,
+ builtins_110_asin,
+ builtins_110_atan,
+ builtins_110_ceil,
+ builtins_110_clamp,
+ builtins_110_cos,
+ builtins_110_cross,
+ builtins_110_degrees,
+ builtins_110_distance,
+ builtins_110_dot,
+ builtins_110_equal,
+ builtins_110_exp,
+ builtins_110_exp2,
+ builtins_110_faceforward,
+ builtins_110_floor,
+ builtins_110_fract,
+ builtins_110_greaterThan,
+ builtins_110_greaterThanEqual,
+ builtins_110_inversesqrt,
+ builtins_110_length,
+ builtins_110_lessThan,
+ builtins_110_lessThanEqual,
+ builtins_110_log,
+ builtins_110_log2,
+ builtins_110_matrixCompMult,
+ builtins_110_max,
+ builtins_110_min,
+ builtins_110_mix,
+ builtins_110_mod,
+ builtins_110_noise_fake,
+ builtins_110_normalize,
+ builtins_110_not,
+ builtins_110_notEqual,
+ builtins_110_pow,
+ builtins_110_radians,
+ builtins_110_reflect,
+ builtins_110_refract,
+ builtins_110_sign,
+ builtins_110_sin,
+ builtins_110_smoothstep,
+ builtins_110_sqrt,
+ builtins_110_step,
+ builtins_110_tan,
+ builtins_110_textures,
+};
+
+/* 110_fs builtins */
+
+static const char *builtins_110_fs_derivatives = {
+ "((function dFdx\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ((return (expression float dFdx (var_ref p)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ((return (expression vec2 dFdx (var_ref p)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ((return (expression vec3 dFdx (var_ref p)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ((return (expression vec4 dFdx (var_ref p)))))\n"
+ " )\n"
+ "\n"
+ " (function dFdy\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ((return (expression float dFdy (var_ref p)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ((return (expression vec2 dFdy (var_ref p)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ((return (expression vec3 dFdy (var_ref p)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ((return (expression vec4 dFdy (var_ref p)))))\n"
+ " )\n"
+ "\n"
+ " (function fwidth\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ((return (expression float +\n"
+ " (expression float abs (expression float dFdx (var_ref p)))\n"
+ " (expression float abs (expression float dFdy (var_ref p)))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ((return (expression vec2 +\n"
+ " (expression vec2 abs (expression vec2 dFdx (var_ref p)))\n"
+ " (expression vec2 abs (expression vec2 dFdy (var_ref p)))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ((return (expression vec3 +\n"
+ " (expression vec3 abs (expression vec3 dFdx (var_ref p)))\n"
+ " (expression vec3 abs (expression vec3 dFdy (var_ref p)))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ((return (expression vec4 +\n"
+ " (expression vec4 abs (expression vec4 dFdx (var_ref p)))\n"
+ " (expression vec4 abs (expression vec4 dFdy (var_ref p)))))))\n"
+ "))\n"
+};
+
+static const char *builtins_110_fs_textures = {
+ "((function texture1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture3D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture3DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *functions_for_110_fs [] = {
+ builtins_110_fs_derivatives,
+ builtins_110_fs_textures,
+};
+
+/* 110_vs builtins */
+
+static const char *builtins_110_vs_ftransform = {
+ "((function ftransform\n"
+ " (signature vec4\n"
+ " (parameters)\n"
+ " ((return (expression vec4 *\n"
+ " (var_ref gl_ModelViewProjectionMatrix)\n"
+ " (var_ref gl_Vertex)))))\n"
+ "))\n"
+};
+
+static const char *functions_for_110_vs [] = {
+ builtins_110_vs_ftransform,
+};
+
+/* 120 builtins */
+
+static const char *builtins_120_matrixCompMult = {
+ "((function matrixCompMult\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) mat2x3 x)\n"
+ " (declare (in) mat2x3 y))\n"
+ " ((declare () mat2x3 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ "(return (var_ref z))))\n"
+ "\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) mat3x2 x)\n"
+ " (declare (in) mat3x2 y))\n"
+ " ((declare () mat3x2 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
+ "(return (var_ref z))))\n"
+ "\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) mat2x4 x)\n"
+ " (declare (in) mat2x4 y))\n"
+ " ((declare () mat2x4 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ "(return (var_ref z))))\n"
+ "\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) mat4x2 x)\n"
+ " (declare (in) mat4x2 y))\n"
+ " ((declare () mat4x2 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec2 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3))))) \n"
+ "(return (var_ref z))))\n"
+ "\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) mat3x4 x)\n"
+ " (declare (in) mat3x4 y))\n"
+ " ((declare () mat3x4 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
+ "(return (var_ref z))))\n"
+ "\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) mat4x3 x)\n"
+ " (declare (in) mat4x3 y))\n"
+ " ((declare () mat4x3 z)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec3 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3))))) \n"
+ "(return (var_ref z))))\n"
+ "))\n"
+};
+
+static const char *builtins_120_outerProduct = {
+ "((function outerProduct\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) vec2 u)\n"
+ " (declare (in) vec2 v))\n"
+ " ((declare () mat2 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) vec2 u)\n"
+ " (declare (in) vec3 v))\n"
+ " ((declare () mat2x3 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) vec2 u)\n"
+ " (declare (in) vec4 v))\n"
+ " ((declare () mat2x4 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) vec3 u)\n"
+ " (declare (in) vec2 v))\n"
+ " ((declare () mat3x2 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) vec3 u)\n"
+ " (declare (in) vec3 v))\n"
+ " ((declare () mat3 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) vec3 u)\n"
+ " (declare (in) vec4 v))\n"
+ " ((declare () mat3x4 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) vec4 u)\n"
+ " (declare (in) vec2 v))\n"
+ " ((declare () mat4x2 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec2 * (var_ref v) (swiz w (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) vec4 u)\n"
+ " (declare (in) vec3 v))\n"
+ " ((declare () mat4x3 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec3 * (var_ref v) (swiz w (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) vec4 u)\n"
+ " (declare (in) vec4 v))\n"
+ " ((declare () mat4 m)\n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u)))) \n"
+ " (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec4 * (var_ref v) (swiz w (var_ref u)))) \n"
+ "(return (var_ref m))))\n"
+ "))\n"
+ "\n"
+};
+
+static const char *builtins_120_transpose = {
+ "((function transpose\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 m))\n"
+ " ((declare () mat2 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) mat2x3 m))\n"
+ " ((declare () mat3x2 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) mat2x4 m))\n"
+ " ((declare () mat4x2 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) mat3x2 m))\n"
+ " ((declare () mat2x3 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 m))\n"
+ " ((declare () mat3 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) mat3x4 m))\n"
+ " ((declare () mat4x3 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) mat4x2 m))\n"
+ " ((declare () mat2x4 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) mat4x3 m))\n"
+ " ((declare () mat3x4 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3))))) \n"
+ "(return (var_ref t))))\n"
+ "\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 m))\n"
+ " ((declare () mat4 t)\n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3))))) \n"
+ " (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (3))))) \n"
+ "(return (var_ref t))))\n"
+ ")\n"
+ "\n"
+ ")\n"
+ "\n"
+};
+
+static const char *functions_for_120 [] = {
+ builtins_120_matrixCompMult,
+ builtins_120_outerProduct,
+ builtins_120_transpose,
+};
+
+/* 130 builtins */
+
+static const char *builtins_130_clamp = {
+ "((function clamp\n"
+ " (signature int\n"
+ " (parameters\n"
+ " (declare (in) int arg0)\n"
+ " (declare (in) int arg1)\n"
+ " (declare (in) int arg2))\n"
+ " ((return (expression int max (expression int min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1)\n"
+ " (declare (in) ivec2 arg2))\n"
+ " ((return (expression ivec2 max (expression ivec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1)\n"
+ " (declare (in) ivec3 arg2))\n"
+ " ((return (expression ivec3 max (expression ivec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1)\n"
+ " (declare (in) ivec4 arg2))\n"
+ " ((return (expression ivec4 max (expression ivec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) int arg1)\n"
+ " (declare (in) int arg2))\n"
+ " ((declare () ivec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) int arg1)\n"
+ " (declare (in) int arg2))\n"
+ " ((declare () ivec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) int arg1)\n"
+ " (declare (in) int arg2))\n"
+ " ((declare () ivec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uint\n"
+ " (parameters\n"
+ " (declare (in) uint arg0)\n"
+ " (declare (in) uint arg1)\n"
+ " (declare (in) uint arg2))\n"
+ " ((return (expression uint max (expression uint min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1)\n"
+ " (declare (in) uvec2 arg2))\n"
+ " ((return (expression uvec2 max (expression uvec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1)\n"
+ " (declare (in) uvec3 arg2))\n"
+ " ((return (expression uvec3 max (expression uvec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1)\n"
+ " (declare (in) uvec4 arg2))\n"
+ " ((return (expression uvec4 max (expression uvec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uint arg1)\n"
+ " (declare (in) uint arg2))\n"
+ " ((declare () uvec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uint arg1)\n"
+ " (declare (in) uint arg2))\n"
+ " ((declare () uvec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uint arg1)\n"
+ " (declare (in) uint arg2))\n"
+ " ((declare () uvec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_cosh = {
+ "((function cosh\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float * (constant float (0.5))\n"
+ " (expression float +\n"
+ " (expression float exp (var_ref x))\n"
+ " (expression float exp (expression float neg (var_ref x))))))))\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 * (constant vec2 (0.5))\n"
+ " (expression vec2 +\n"
+ " (expression vec2 exp (var_ref x))\n"
+ " (expression vec2 exp (expression vec2 neg (var_ref x))))))))\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 * (constant vec3 (0.5))\n"
+ " (expression vec3 +\n"
+ " (expression vec3 exp (var_ref x))\n"
+ " (expression vec3 exp (expression vec3 neg (var_ref x))))))))\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 * (constant vec4 (0.5))\n"
+ " (expression vec4 +\n"
+ " (expression vec4 exp (var_ref x))\n"
+ " (expression vec4 exp (expression vec4 neg (var_ref x))))))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_equal = {
+ "((function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_greaterThan = {
+ "((function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_greaterThanEqual = {
+ "((function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_lessThan = {
+ "((function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_lessThanEqual = {
+ "((function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_max = {
+ "((function max\n"
+ " (signature int\n"
+ " (parameters\n"
+ " (declare (in) int arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((return (expression int max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression ivec2 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression ivec3 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression ivec4 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((declare () ivec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((declare () ivec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((declare () ivec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result))\n"
+ " (expression int max (swiz w (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uint\n"
+ " (parameters\n"
+ " (declare (in) uint arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((return (expression uint max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression uvec2 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression uvec3 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression uvec4 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((declare () uvec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((declare () uvec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((declare () uvec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result))\n"
+ " (expression uint max (swiz w (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_min = {
+ "((function min\n"
+ " (signature int\n"
+ " (parameters\n"
+ " (declare (in) int arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((return (expression int min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression ivec2 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression ivec3 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression ivec4 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((declare () ivec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((declare () ivec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) int arg1))\n"
+ " ((declare () ivec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result))\n"
+ " (expression int min (swiz w (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uint\n"
+ " (parameters\n"
+ " (declare (in) uint arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((return (expression uint min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression uvec2 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression uvec3 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression uvec4 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((declare () uvec2 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((declare () uvec3 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uint arg1))\n"
+ " ((declare () uvec4 result)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref result))\n"
+ " (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref result))\n"
+ " (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref result))\n"
+ " (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref result))\n"
+ " (expression uint min (swiz w (var_ref arg0)) (var_ref arg1)))\n"
+ " (return (var_ref result))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_notEqual = {
+ "((function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((declare () bvec2 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((declare () bvec3 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((declare () bvec4 temp)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1)))) \n"
+ " (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool != (swiz w (var_ref arg0))(swiz w (var_ref arg1)))) \n"
+ " (return (var_ref temp))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_sign = {
+ "((function sign\n"
+ " (signature int\n"
+ " (parameters\n"
+ " (declare (in) int x))\n"
+ " ((return (expression int / (var_ref x) (expression int abs (var_ref x))))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x))\n"
+ " ((declare () ivec2 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x))\n"
+ " ((declare () ivec3 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))\n"
+ " (return (var_ref t))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x))\n"
+ " ((declare () ivec4 t)\n"
+ " (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))\n"
+ " (assign (constant bool (1)) (swiz w (var_ref t)) (expression int sign (swiz w (var_ref x))))\n"
+ " (return (var_ref t))))\n"
+ "))\n"
+ "\n"
+};
+
+static const char *builtins_130_sinh = {
+ "((function sinh\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float * (constant float (0.5))\n"
+ " (expression float -\n"
+ " (expression float exp (var_ref x))\n"
+ " (expression float exp (expression float neg (var_ref x))))))))\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 * (constant vec2 (0.5))\n"
+ " (expression vec2 -\n"
+ " (expression vec2 exp (var_ref x))\n"
+ " (expression vec2 exp (expression vec2 neg (var_ref x))))))))\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 * (constant vec3 (0.5))\n"
+ " (expression vec3 -\n"
+ " (expression vec3 exp (var_ref x))\n"
+ " (expression vec3 exp (expression vec3 neg (var_ref x))))))))\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 * (constant vec4 (0.5))\n"
+ " (expression vec4 -\n"
+ " (expression vec4 exp (var_ref x))\n"
+ " (expression vec4 exp (expression vec4 neg (var_ref x))))))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_tanh = {
+ "((function tanh\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float /\n"
+ " (expression float -\n"
+ " (expression float exp (var_ref x))\n"
+ " (expression float exp (expression float neg (var_ref x))))\n"
+ " (expression float +\n"
+ " (expression float exp (var_ref x))\n"
+ " (expression float exp (expression float neg (var_ref x))))))))\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 /\n"
+ " (expression vec2 -\n"
+ " (expression vec2 exp (var_ref x))\n"
+ " (expression vec2 exp (expression vec2 neg (var_ref x))))\n"
+ " (expression vec2 +\n"
+ " (expression vec2 exp (var_ref x))\n"
+ " (expression vec2 exp (expression vec2 neg (var_ref x))))))))\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 /\n"
+ " (expression vec3 -\n"
+ " (expression vec3 exp (var_ref x))\n"
+ " (expression vec3 exp (expression vec3 neg (var_ref x))))\n"
+ " (expression vec3 +\n"
+ " (expression vec3 exp (var_ref x))\n"
+ " (expression vec3 exp (expression vec3 neg (var_ref x))))))))\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 /\n"
+ " (expression vec4 -\n"
+ " (expression vec4 exp (var_ref x))\n"
+ " (expression vec4 exp (expression vec4 neg (var_ref x))))\n"
+ " (expression vec4 +\n"
+ " (expression vec4 exp (var_ref x))\n"
+ " (expression vec4 exp (expression vec4 neg (var_ref x))))))))\n"
+ "))\n"
+};
+
+static const char *builtins_130_texelFetch = {
+ "((function texelFetch\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) int P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) int P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) int P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) ivec2 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) ivec2 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) ivec2 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) ivec3 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) ivec3 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) ivec3 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) ivec2 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1DArray sampler)\n"
+ " (declare (in) ivec2 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1DArray sampler)\n"
+ " (declare (in) ivec2 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) ivec3 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2DArray sampler)\n"
+ " (declare (in) ivec3 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2DArray sampler)\n"
+ " (declare (in) ivec3 P) \n"
+ " (declare (in) int lod) )\n"
+ " ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_130_texture = {
+ "((function texture\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) float P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) float P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isamplerCube sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usamplerCube sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1DArray sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1DArray sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2DArray sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2DArray sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_130_textureGrad = {
+ "((function textureGrad\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isamplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usamplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ ")\n"
+ ")\n"
+};
+
+static const char *builtins_130_textureLod = {
+ "((function textureLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isamplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usamplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_130_textureProj = {
+ "((function textureProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_130_textureProjGrad = {
+ "((function textureLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float dPdx) \n"
+ " (declare (in) float dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) vec2 dPdx) \n"
+ " (declare (in) vec2 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) vec3 dPdx) \n"
+ " (declare (in) vec3 dPdy) )\n"
+ " ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_130_textureProjLod = {
+ "((function textureLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *functions_for_130 [] = {
+ builtins_130_clamp,
+ builtins_130_cosh,
+ builtins_130_equal,
+ builtins_130_greaterThan,
+ builtins_130_greaterThanEqual,
+ builtins_130_lessThan,
+ builtins_130_lessThanEqual,
+ builtins_130_max,
+ builtins_130_min,
+ builtins_130_notEqual,
+ builtins_130_sign,
+ builtins_130_sinh,
+ builtins_130_tanh,
+ builtins_130_texelFetch,
+ builtins_130_texture,
+ builtins_130_textureGrad,
+ builtins_130_textureLod,
+ builtins_130_textureProj,
+ builtins_130_textureProjGrad,
+ builtins_130_textureProjLod,
+};
+
+/* 130_fs builtins */
+
+static const char *builtins_130_fs_texture = {
+ "((function texture\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) float P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isamplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usamplerCube sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *builtins_130_fs_textureProj = {
+ "((function textureProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler1D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler2D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) isampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ " (signature uvec4\n"
+ " (parameters\n"
+ " (declare (in) usampler3D sampler)\n"
+ " (declare (in) vec4 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *functions_for_130_fs [] = {
+ builtins_130_fs_texture,
+ builtins_130_fs_textureProj,
+};
+
+/* ARB_texture_rectangle builtins */
+
+static const char *builtins_ARB_texture_rectangle_textures = {
+ "((function texture2DRect\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2DRect\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRectShadow sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *functions_for_ARB_texture_rectangle [] = {
+ builtins_ARB_texture_rectangle_textures,
+};
+
+/* EXT_texture_array builtins */
+
+static const char *builtins_EXT_texture_array_textures = {
+ "((function texture1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ ")\n"
+ " (function texture1DArrayLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2DArrayLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArrayShadow sampler)\n"
+ " (declare (in) vec3 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1DArrayLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArrayShadow sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float lod) )\n"
+ " ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow2DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArrayShadow sampler)\n"
+ " (declare (in) vec4 P) )\n"
+ " ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) 1 (swiz w (var_ref P)) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *functions_for_EXT_texture_array [] = {
+ builtins_EXT_texture_array_textures,
+};
+
+/* EXT_texture_array_fs builtins */
+
+static const char *builtins_EXT_texture_array_fs_textures = {
+ "((function texture1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function texture2DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))\n"
+ "\n"
+ ")\n"
+ " (function shadow1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArrayShadow sampler)\n"
+ " (declare (in) vec3 P) \n"
+ " (declare (in) float bias) )\n"
+ " ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))\n"
+ "\n"
+ "))\n"
+};
+
+static const char *functions_for_EXT_texture_array_fs [] = {
+ builtins_EXT_texture_array_fs_textures,
+};
+
+void
+_mesa_glsl_initialize_functions(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (state->language_version >= 110)
+ read_builtins(state, instructions,
+ functions_for_110,
+ sizeof(functions_for_110) / sizeof(const char *));
+
+ if (state->target == fragment_shader && state->language_version >= 110)
+ read_builtins(state, instructions,
+ functions_for_110_fs,
+ sizeof(functions_for_110_fs) / sizeof(const char *));
+
+ if (state->target == vertex_shader && state->language_version >= 110)
+ read_builtins(state, instructions,
+ functions_for_110_vs,
+ sizeof(functions_for_110_vs) / sizeof(const char *));
+
+ if (state->language_version >= 120)
+ read_builtins(state, instructions,
+ functions_for_120,
+ sizeof(functions_for_120) / sizeof(const char *));
+
+ if (state->language_version >= 130)
+ read_builtins(state, instructions,
+ functions_for_130,
+ sizeof(functions_for_130) / sizeof(const char *));
+
+ if (state->target == fragment_shader && state->language_version >= 130)
+ read_builtins(state, instructions,
+ functions_for_130_fs,
+ sizeof(functions_for_130_fs) / sizeof(const char *));
+
+ if (state->ARB_texture_rectangle_enable)
+ read_builtins(state, instructions,
+ functions_for_ARB_texture_rectangle,
+ sizeof(functions_for_ARB_texture_rectangle) / sizeof(const char *));
+
+ if (state->EXT_texture_array_enable)
+ read_builtins(state, instructions,
+ functions_for_EXT_texture_array,
+ sizeof(functions_for_EXT_texture_array) / sizeof(const char *));
+
+ if (state->target == fragment_shader && state->EXT_texture_array_enable)
+ read_builtins(state, instructions,
+ functions_for_EXT_texture_array_fs,
+ sizeof(functions_for_EXT_texture_array_fs) / sizeof(const char *));
+
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef Elements
+#define Elements(x) (sizeof(x)/sizeof(*(x)))
+#endif
+
+static const struct glsl_type _error_type =
+ glsl_type(GLSL_TYPE_ERROR, 0, 0, "");
+
+static const struct glsl_type void_type =
+ glsl_type(GLSL_TYPE_VOID, 0, 0, "void");
+
+const glsl_type *const glsl_type::error_type = & _error_type;
+
+/** \name Core built-in types
+ *
+ * These types exist in all versions of GLSL.
+ */
+/*@{*/
+
+static const struct glsl_type builtin_core_types[] = {
+ glsl_type( GLSL_TYPE_BOOL, 1, 1, "bool"),
+ glsl_type( GLSL_TYPE_BOOL, 2, 1, "bvec2"),
+ glsl_type( GLSL_TYPE_BOOL, 3, 1, "bvec3"),
+ glsl_type( GLSL_TYPE_BOOL, 4, 1, "bvec4"),
+ glsl_type( GLSL_TYPE_INT, 1, 1, "int"),
+ glsl_type( GLSL_TYPE_INT, 2, 1, "ivec2"),
+ glsl_type( GLSL_TYPE_INT, 3, 1, "ivec3"),
+ glsl_type( GLSL_TYPE_INT, 4, 1, "ivec4"),
+ glsl_type( GLSL_TYPE_FLOAT, 1, 1, "float"),
+ glsl_type( GLSL_TYPE_FLOAT, 2, 1, "vec2"),
+ glsl_type( GLSL_TYPE_FLOAT, 3, 1, "vec3"),
+ glsl_type( GLSL_TYPE_FLOAT, 4, 1, "vec4"),
+ glsl_type( GLSL_TYPE_FLOAT, 2, 2, "mat2"),
+ glsl_type( GLSL_TYPE_FLOAT, 3, 3, "mat3"),
+ glsl_type( GLSL_TYPE_FLOAT, 4, 4, "mat4"),
+ glsl_type( GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT, "sampler1D"),
+ glsl_type( GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT, "sampler1DShadow"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT, "sampler2D"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT, "sampler2DShadow"),
+ glsl_type( GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT, "sampler3D"),
+ glsl_type(GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT, "samplerCube"),
+};
+
+const glsl_type *const glsl_type::bool_type = & builtin_core_types[0];
+const glsl_type *const glsl_type::int_type = & builtin_core_types[4];
+const glsl_type *const glsl_type::ivec4_type = & builtin_core_types[7];
+const glsl_type *const glsl_type::float_type = & builtin_core_types[8];
+const glsl_type *const glsl_type::vec2_type = & builtin_core_types[9];
+const glsl_type *const glsl_type::vec3_type = & builtin_core_types[10];
+const glsl_type *const glsl_type::vec4_type = & builtin_core_types[11];
+const glsl_type *const glsl_type::mat2_type = & builtin_core_types[12];
+const glsl_type *const glsl_type::mat3_type = & builtin_core_types[13];
+const glsl_type *const glsl_type::mat4_type = & builtin_core_types[14];
+/*@}*/
+
+/** \name GLSL structures that have not been deprecated.
+ */
+/*@{*/
+
+static const struct glsl_struct_field gl_DepthRangeParameters_fields[] = {
+ { glsl_type::float_type, "near" },
+ { glsl_type::float_type, "far" },
+ { glsl_type::float_type, "diff" },
+};
+
+static const struct glsl_type builtin_structure_types[] = {
+ glsl_type(gl_DepthRangeParameters_fields,
+ Elements(gl_DepthRangeParameters_fields),
+ "gl_DepthRangeParameters"),
+};
+/*@}*/
+
+/** \name GLSL 1.00 / 1.10 structures that are deprecated in GLSL 1.30
+ */
+/*@{*/
+
+static const struct glsl_struct_field gl_PointParameters_fields[] = {
+ { glsl_type::float_type, "size" },
+ { glsl_type::float_type, "sizeMin" },
+ { glsl_type::float_type, "sizeMax" },
+ { glsl_type::float_type, "fadeThresholdSize" },
+ { glsl_type::float_type, "distanceConstantAttenuation" },
+ { glsl_type::float_type, "distanceLinearAttenuation" },
+ { glsl_type::float_type, "distanceQuadraticAttenuation" },
+};
+
+static const struct glsl_struct_field gl_MaterialParameters_fields[] = {
+ { glsl_type::vec4_type, "emission" },
+ { glsl_type::vec4_type, "ambient" },
+ { glsl_type::vec4_type, "diffuse" },
+ { glsl_type::vec4_type, "specular" },
+ { glsl_type::float_type, "shininess" },
+};
+
+static const struct glsl_struct_field gl_LightSourceParameters_fields[] = {
+ { glsl_type::vec4_type, "ambient" },
+ { glsl_type::vec4_type, "diffuse" },
+ { glsl_type::vec4_type, "specular" },
+ { glsl_type::vec4_type, "position" },
+ { glsl_type::vec4_type, "halfVector" },
+ { glsl_type::vec3_type, "spotDirection" },
+ { glsl_type::float_type, "spotExponent" },
+ { glsl_type::float_type, "spotCutoff" },
+ { glsl_type::float_type, "spotCosCutoff" },
+ { glsl_type::float_type, "constantAttenuation" },
+ { glsl_type::float_type, "linearAttenuation" },
+ { glsl_type::float_type, "quadraticAttenuation" },
+};
+
+static const struct glsl_struct_field gl_LightModelParameters_fields[] = {
+ { glsl_type::vec4_type, "ambient" },
+};
+
+static const struct glsl_struct_field gl_LightModelProducts_fields[] = {
+ { glsl_type::vec4_type, "sceneColor" },
+};
+
+static const struct glsl_struct_field gl_LightProducts_fields[] = {
+ { glsl_type::vec4_type, "ambient" },
+ { glsl_type::vec4_type, "diffuse" },
+ { glsl_type::vec4_type, "specular" },
+};
+
+static const struct glsl_struct_field gl_FogParameters_fields[] = {
+ { glsl_type::vec4_type, "color" },
+ { glsl_type::float_type, "density" },
+ { glsl_type::float_type, "start" },
+ { glsl_type::float_type, "end" },
+ { glsl_type::float_type, "scale" },
+};
+
+static const struct glsl_type builtin_110_deprecated_structure_types[] = {
+ glsl_type(gl_PointParameters_fields,
+ Elements(gl_PointParameters_fields),
+ "gl_PointParameters"),
+ glsl_type(gl_MaterialParameters_fields,
+ Elements(gl_MaterialParameters_fields),
+ "gl_MaterialParameters"),
+ glsl_type(gl_LightSourceParameters_fields,
+ Elements(gl_LightSourceParameters_fields),
+ "gl_LightSourceParameters"),
+ glsl_type(gl_LightModelParameters_fields,
+ Elements(gl_LightModelParameters_fields),
+ "gl_LightModelParameters"),
+ glsl_type(gl_LightModelProducts_fields,
+ Elements(gl_LightModelProducts_fields),
+ "gl_LightModelProducts"),
+ glsl_type(gl_LightProducts_fields,
+ Elements(gl_LightProducts_fields),
+ "gl_LightProducts"),
+ glsl_type(gl_FogParameters_fields,
+ Elements(gl_FogParameters_fields),
+ "gl_FogParameters"),
+};
+/*@}*/
+
+/** \name Types added in GLSL 1.20
+ */
+/*@{*/
+
+static const struct glsl_type builtin_120_types[] = {
+ glsl_type( GLSL_TYPE_FLOAT, 3, 2, "mat2x3"),
+ glsl_type( GLSL_TYPE_FLOAT, 4, 2, "mat2x4"),
+ glsl_type( GLSL_TYPE_FLOAT, 2, 3, "mat3x2"),
+ glsl_type( GLSL_TYPE_FLOAT, 4, 3, "mat3x4"),
+ glsl_type( GLSL_TYPE_FLOAT, 2, 4, "mat4x2"),
+ glsl_type( GLSL_TYPE_FLOAT, 3, 4, "mat4x3"),
+};
+const glsl_type *const glsl_type::mat2x3_type = & builtin_120_types[0];
+const glsl_type *const glsl_type::mat2x4_type = & builtin_120_types[1];
+const glsl_type *const glsl_type::mat3x2_type = & builtin_120_types[2];
+const glsl_type *const glsl_type::mat3x4_type = & builtin_120_types[3];
+const glsl_type *const glsl_type::mat4x2_type = & builtin_120_types[4];
+const glsl_type *const glsl_type::mat4x3_type = & builtin_120_types[5];
+/*@}*/
+
+/** \name Types added in GLSL 1.30
+ */
+/*@{*/
+
+static const struct glsl_type builtin_130_types[] = {
+ glsl_type( GLSL_TYPE_UINT, 1, 1, "uint"),
+ glsl_type( GLSL_TYPE_UINT, 2, 1, "uvec2"),
+ glsl_type( GLSL_TYPE_UINT, 3, 1, "uvec3"),
+ glsl_type( GLSL_TYPE_UINT, 4, 1, "uvec4"),
+
+ /* 1D and 2D texture arrays */
+ glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT, "sampler1DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT, "isampler1DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT, "usampler1DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT, "sampler1DArrayShadow"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT, "sampler2DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT, "isampler2DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT, "usampler2DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT, "sampler2DArrayShadow"),
+
+ /* cube shadow samplers */
+ glsl_type(GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT, "samplerCubeShadow"),
+
+ /* signed and unsigned integer samplers */
+ glsl_type( GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT, "isampler1D"),
+ glsl_type( GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT, "usampler1D"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT, "isampler2D"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT, "usampler2D"),
+ glsl_type( GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT, "isampler3D"),
+ glsl_type( GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT, "usampler3D"),
+ glsl_type(GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT, "isamplerCube"),
+ glsl_type(GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT, "usamplerCube"),
+};
+
+const glsl_type *const glsl_type::uint_type = & builtin_130_types[0];
+const glsl_type *const glsl_type::uvec4_type = & builtin_130_types[3];
+/*@}*/
+
+/** \name Sampler types added by GL_ARB_texture_rectangle
+ */
+/*@{*/
+
+static const struct glsl_type builtin_ARB_texture_rectangle_types[] = {
+ glsl_type(GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT, "sampler2DRect"),
+ glsl_type(GLSL_SAMPLER_DIM_RECT, 1, 0, GLSL_TYPE_FLOAT, "sampler2DRectShadow"),
+};
+/*@}*/
+
+/** \name Sampler types added by GL_EXT_texture_array
+ */
+/*@{*/
+
+static const struct glsl_type builtin_EXT_texture_array_types[] = {
+ glsl_type( GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT, "sampler1DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT, "sampler2DArray"),
+ glsl_type( GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT, "sampler1DArrayShadow"),
+ glsl_type( GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT, "sampler2DArrayShadow"),
+};
+/*@}*/
+
+/** \name Sampler types added by GL_EXT_texture_buffer_object
+ */
+/*@{*/
+
+static const struct glsl_type builtin_EXT_texture_buffer_object_types[] = {
+ glsl_type( GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT, "samplerBuffer"),
+ glsl_type( GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT, "isamplerBuffer"),
+ glsl_type( GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT, "usamplerBuffer"),
+};
+/*@}*/
--- /dev/null
+/*
+ * 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 "main/mtypes.h"
+
+struct builtin_variable {
+ enum ir_variable_mode mode;
+ int slot;
+ const char *type;
+ const char *name;
+};
+
+static const builtin_variable builtin_core_vs_variables[] = {
+ { ir_var_out, VERT_RESULT_HPOS, "vec4", "gl_Position" },
+ { ir_var_out, VERT_RESULT_PSIZ, "float", "gl_PointSize" },
+};
+
+static const builtin_variable builtin_core_fs_variables[] = {
+ { ir_var_in, FRAG_ATTRIB_WPOS, "vec4", "gl_FragCoord" },
+ { ir_var_in, FRAG_ATTRIB_FACE, "bool", "gl_FrontFacing" },
+ { ir_var_out, FRAG_RESULT_COLOR, "vec4", "gl_FragColor" },
+ { ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" },
+};
+
+static const builtin_variable builtin_110_deprecated_fs_variables[] = {
+ { ir_var_in, FRAG_ATTRIB_COL0, "vec4", "gl_Color" },
+ { ir_var_in, FRAG_ATTRIB_COL1, "vec4", "gl_SecondaryColor" },
+ { ir_var_in, FRAG_ATTRIB_FOGC, "float", "gl_FogFragCoord" },
+};
+
+static const builtin_variable builtin_110_deprecated_vs_variables[] = {
+ { ir_var_in, VERT_ATTRIB_POS, "vec4", "gl_Vertex" },
+ { ir_var_in, VERT_ATTRIB_NORMAL, "vec3", "gl_Normal" },
+ { ir_var_in, VERT_ATTRIB_COLOR0, "vec4", "gl_Color" },
+ { ir_var_in, VERT_ATTRIB_COLOR1, "vec4", "gl_SecondaryColor" },
+ { ir_var_in, VERT_ATTRIB_TEX0, "vec4", "gl_MultiTexCoord0" },
+ { ir_var_in, VERT_ATTRIB_TEX1, "vec4", "gl_MultiTexCoord1" },
+ { ir_var_in, VERT_ATTRIB_TEX2, "vec4", "gl_MultiTexCoord2" },
+ { ir_var_in, VERT_ATTRIB_TEX3, "vec4", "gl_MultiTexCoord3" },
+ { ir_var_in, VERT_ATTRIB_TEX4, "vec4", "gl_MultiTexCoord4" },
+ { ir_var_in, VERT_ATTRIB_TEX5, "vec4", "gl_MultiTexCoord5" },
+ { ir_var_in, VERT_ATTRIB_TEX6, "vec4", "gl_MultiTexCoord6" },
+ { ir_var_in, VERT_ATTRIB_TEX7, "vec4", "gl_MultiTexCoord7" },
+ { ir_var_in, VERT_ATTRIB_FOG, "float", "gl_FogCoord" },
+ { ir_var_out, VERT_RESULT_HPOS, "vec4", "gl_ClipVertex" },
+ { ir_var_out, VERT_RESULT_COL0, "vec4", "gl_FrontColor" },
+ { ir_var_out, VERT_RESULT_BFC0, "vec4", "gl_BackColor" },
+ { ir_var_out, VERT_RESULT_COL1, "vec4", "gl_FrontSecondaryColor" },
+ { ir_var_out, VERT_RESULT_BFC1, "vec4", "gl_BackSecondaryColor" },
+ { ir_var_out, VERT_RESULT_FOGC, "float", "gl_FogFragCoord" },
+};
+
+static const builtin_variable builtin_130_vs_variables[] = {
+ { ir_var_in, -1, "int", "gl_VertexID" },
+};
+
+static const builtin_variable builtin_110_deprecated_uniforms[] = {
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrix" },
+ { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrix" },
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrix" },
+ { ir_var_uniform, -1, "mat3", "gl_NormalMatrix" },
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverse" },
+ { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverse" },
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverse" },
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixTranspose" },
+ { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixTranspose" },
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixTranspose" },
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverseTranspose" },
+ { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverseTranspose" },
+ { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverseTranspose" },
+ { ir_var_uniform, -1, "float", "gl_NormalScale" },
+};
+
--- /dev/null
+((function abs
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float abs (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 abs (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 abs (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 abs (var_ref arg0)))))
+))
--- /dev/null
+((function all
+ (signature bool
+ (parameters
+ (declare (in) bvec2 arg0))
+ ((return (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))
+
+ (signature bool
+ (parameters
+ (declare (in) bvec3 arg0))
+ ((return (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))
+
+ (signature bool
+ (parameters
+ (declare (in) bvec4 arg0))
+ ((return (expression bool && (expression bool && (expression bool && (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))
+))
--- /dev/null
+((function any
+ (signature bool
+ (parameters
+ (declare (in) bvec2 arg0))
+ ((return (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))))))
+
+ (signature bool
+ (parameters
+ (declare (in) bvec3 arg0))
+ ((return (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))))))
+
+ (signature bool
+ (parameters
+ (declare (in) bvec4 arg0))
+ ((return (expression bool || (expression bool || (expression bool || (swiz x (var_ref arg0))(swiz y (var_ref arg0))) (swiz z (var_ref arg0))) (swiz w (var_ref arg0))))))
+))
--- /dev/null
+((function asin
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (expression float *
+ (expression float -
+ (expression float *
+ (constant float (3.1415926))
+ (constant float (0.5)))
+ (expression float sqrt
+ (expression float -
+ (constant float (1.0))
+ (expression float abs (var_ref x)))))
+ (expression float +
+ (constant float (1.5707288))
+ (expression float *
+ (expression float abs (var_ref x))
+ (expression float +
+ (constant float (-0.2121144))
+ (expression float *
+ (constant float (0.0742610))
+ (expression float abs (var_ref x))))))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((return (expression vec2 *
+ (expression float -
+ (expression float *
+ (constant float (3.1415926))
+ (constant float (0.5)))
+ (expression vec2 sqrt
+ (expression vec2 -
+ (constant float (1.0))
+ (expression vec2 abs (var_ref x)))))
+ (expression vec2 +
+ (constant float (1.5707288))
+ (expression vec2 *
+ (expression vec2 abs (var_ref x))
+ (expression vec2 +
+ (constant float (-0.2121144))
+ (expression vec2 *
+ (constant float (0.0742610))
+ (expression vec2 abs (var_ref x))))))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((return (expression vec3 *
+ (expression vec3 -
+ (expression float *
+ (constant float (3.1415926))
+ (constant float (0.5)))
+ (expression vec3 sqrt
+ (expression vec3 -
+ (constant float (1.0))
+ (expression vec3 abs (var_ref x)))))
+ (expression vec3 +
+ (constant float (1.5707288))
+ (expression vec3 *
+ (expression vec3 abs (var_ref x))
+ (expression vec3 +
+ (constant float (-0.2121144))
+ (expression vec3 *
+ (constant float (0.0742610))
+ (expression vec3 abs (var_ref x))))))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((return (expression vec4 *
+ (expression vec4 -
+ (expression float *
+ (constant float (3.1415926))
+ (constant float (0.5)))
+ (expression vec4 sqrt
+ (expression vec4 -
+ (constant float (1.0))
+ (expression vec4 abs (var_ref x)))))
+ (expression vec4 +
+ (constant float (1.5707288))
+ (expression vec4 *
+ (expression vec4 abs (var_ref x))
+ (expression vec4 +
+ (constant float (-0.2121144))
+ (expression vec4 *
+ (constant float (0.0742610))
+ (expression vec4 abs (var_ref x))))))))))
+)
+
+ (function acos
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (expression float - (constant float (1.5707963))
+ (call asin ((var_ref x)))))))
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((return (expression vec2 - (constant float (1.5707963))
+ (call asin ((var_ref x)))))))
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((return (expression vec3 - (constant float (1.5707963))
+ (call asin ((var_ref x)))))))
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((return (expression vec4 - (constant float (1.5707963))
+ (call asin ((var_ref x)))))))
+))
--- /dev/null
+((function atan
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (call asin ((expression float *
+ (var_ref x)
+ (expression float rsq
+ (expression float +
+ (expression float *
+ (var_ref x)
+ (var_ref x))
+ (constant float (1.0))))))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 y_over_x))
+ ((return (call asin ((expression vec2 *
+ (var_ref y_over_x)
+ (expression vec2 rsq
+ (expression vec2 +
+ (expression vec2 *
+ (var_ref y_over_x)
+ (var_ref y_over_x))
+ (constant float (1.0))))))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 y_over_x))
+ ((return (call asin ((expression vec3 *
+ (var_ref y_over_x)
+ (expression vec3 rsq
+ (expression vec3 +
+ (expression vec3 *
+ (var_ref y_over_x)
+ (var_ref y_over_x))
+ (constant float (1.0))))))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 y_over_x))
+ ((return (call asin ((expression vec4 *
+ (var_ref y_over_x)
+ (expression vec4 rsq
+ (expression vec4 +
+ (expression vec4 *
+ (var_ref y_over_x)
+ (var_ref y_over_x))
+ (constant float (1.0))))))))))
+
+ (signature float
+ (parameters
+ (declare (in) float y)
+ (declare (in) float x))
+ ((declare () float r)
+ (if (expression bool >
+ (expression float abs (var_ref x))
+ (constant float (.0001)))
+ ((assign (constant bool (1))
+ (var_ref r) (call atan ((expression float /
+ (var_ref y)
+ (var_ref x)))))
+ (if (expression bool <
+ (var_ref x)
+ (constant float (0.0)))
+ ((assign (constant bool (1))
+ (var_ref r)
+ (expression float +
+ (var_ref r)
+ (expression float *
+ (expression int sign (var_ref y))
+ (constant float (3.1415926))))))
+ ()))
+ ())
+ (return (var_ref r))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 y)
+ (declare (in) vec2 x))
+ ((declare () vec2 r)
+ (if (expression bool >
+ (expression vec2 abs (var_ref x))
+ (constant float (.0001)))
+ ((assign (constant bool (1))
+ (var_ref r) (call atan ((expression vec2 /
+ (var_ref y)
+ (var_ref x)))))
+ (if (expression bool <
+ (var_ref x)
+ (constant float (0.0)))
+ ((assign (constant bool (1))
+ (var_ref r)
+ (expression vec2 +
+ (var_ref r)
+ (expression vec2 *
+ (expression int sign (var_ref y))
+ (constant float (3.1415926))))))
+ ()))
+ ())
+ (return (var_ref r))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 y)
+ (declare (in) vec3 x))
+ ((declare () vec3 r)
+ (if (expression bool >
+ (expression vec3 abs (var_ref x))
+ (constant float (.0001)))
+ ((assign (constant bool (1))
+ (var_ref r) (call atan ((expression vec3 /
+ (var_ref y)
+ (var_ref x)))))
+ (if (expression bool <
+ (var_ref x)
+ (constant float (0.0)))
+ ((assign (constant bool (1))
+ (var_ref r)
+ (expression vec3 +
+ (var_ref r)
+ (expression vec3 *
+ (expression int sign (var_ref y))
+ (constant float (3.1415926))))))
+ ()))
+ ())
+ (return (var_ref r))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 y)
+ (declare (in) vec4 x))
+ ((declare () vec4 r)
+ (if (expression bool >
+ (expression vec4 abs (var_ref x))
+ (constant float (.0001)))
+ ((assign (constant bool (1))
+ (var_ref r) (call atan ((expression vec4 /
+ (var_ref y)
+ (var_ref x)))))
+ (if (expression bool <
+ (var_ref x)
+ (constant float (0.0)))
+ ((assign (constant bool (1))
+ (var_ref r)
+ (expression vec4 +
+ (var_ref r)
+ (expression vec4 *
+ (expression int sign (var_ref y))
+ (constant float (3.1415926))))))
+ ()))
+ ())
+ (return (var_ref r))))
+
+))
--- /dev/null
+((function ceil
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float ceil (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 ceil (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 ceil (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 ceil (var_ref arg0)))))
+))
--- /dev/null
+((function clamp
+ (signature float
+ (parameters
+ (declare (in) float arg0)
+ (declare (in) float arg1)
+ (declare (in) float arg2))
+ ((return (expression float max (expression float min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1)
+ (declare (in) vec2 arg2))
+ ((return (expression vec2 max (expression vec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1)
+ (declare (in) vec3 arg2))
+ ((return (expression vec3 max (expression vec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1)
+ (declare (in) vec4 arg2))
+ ((return (expression vec4 max (expression vec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) float arg1)
+ (declare (in) float arg2))
+ ((declare () vec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) float arg1)
+ (declare (in) float arg2))
+ ((declare () vec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) float arg1)
+ (declare (in) float arg2))
+ ((declare () vec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression vec4 max (expression vec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression vec4 max (expression vec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result)) (expression vec4 max (expression vec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result)) (expression vec4 max (expression vec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+))
--- /dev/null
+((function cos
+ (signature float
+ (parameters
+ (declare (in) float angle))
+ ((return (expression float cos (var_ref angle)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 angle))
+ ((return (expression vec2 cos (var_ref angle)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 angle))
+ ((return (expression vec3 cos (var_ref angle)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 angle))
+ ((return (expression vec4 cos (var_ref angle)))))
+))
--- /dev/null
+((function cross
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((declare () vec3 t)
+ (assign (constant bool (1)) (swiz x (var_ref t))
+ (expression float - (expression float * (swiz y (var_ref arg0)) (swiz z (var_ref arg1)))
+ (expression float * (swiz y (var_ref arg1)) (swiz z (var_ref arg0)))))
+ (assign (constant bool (1)) (swiz y (var_ref t))
+ (expression float - (expression float * (swiz z (var_ref arg0)) (swiz x (var_ref arg1)))
+ (expression float * (swiz z (var_ref arg1)) (swiz x (var_ref arg0)))))
+ (assign (constant bool (1)) (swiz z (var_ref t))
+ (expression float - (expression float * (swiz x (var_ref arg0)) (swiz y (var_ref arg1)))
+ (expression float * (swiz x (var_ref arg1)) (swiz y (var_ref arg0)))))
+ (return (var_ref t))))
+))
--- /dev/null
+((function degrees
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float * (var_ref arg0) (constant float (57.295780))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 * (var_ref arg0) (constant float (57.295780))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 * (var_ref arg0) (constant float (57.295780))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 * (var_ref arg0) (constant float (57.295780))))))
+))
--- /dev/null
+((function distance
+ (signature float
+ (parameters
+ (declare (in) float p0)
+ (declare (in) float p1))
+ ((declare () float p)
+ (assign (constant bool (1)) (var_ref p) (expression float - (var_ref p0) (var_ref p1)))
+ (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
+
+ (signature float
+ (parameters
+ (declare (in) vec2 p0)
+ (declare (in) vec2 p1))
+ ((declare () vec2 p)
+ (assign (constant bool (1)) (var_ref p) (expression vec2 - (var_ref p0) (var_ref p1)))
+ (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
+
+ (signature float
+ (parameters
+ (declare (in) vec3 p0)
+ (declare (in) vec3 p1))
+ ((declare () vec3 p)
+ (assign (constant bool (1)) (var_ref p) (expression vec3 - (var_ref p0) (var_ref p1)))
+ (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
+
+ (signature float
+ (parameters
+ (declare (in) vec4 p0)
+ (declare (in) vec4 p1))
+ ((declare () vec4 p)
+ (assign (constant bool (1)) (var_ref p) (expression vec4 - (var_ref p0) (var_ref p1)))
+ (return (expression float sqrt (expression float dot (var_ref p) (var_ref p))))))
+))
--- /dev/null
+((function dot
+ (signature float
+ (parameters
+ (declare (in) float arg0)
+ (declare (in) float arg1))
+ ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
+
+ (signature float
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
+
+ (signature float
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
+
+ (signature float
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((return (expression float dot (var_ref arg0) (var_ref arg1)))))
+))
--- /dev/null
+((function equal
+ (signature bvec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function exp
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float exp (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 exp (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 exp (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 exp (var_ref arg0)))))
+))
--- /dev/null
+((function exp2
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float exp2 (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 exp2 (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 exp2 (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 exp2 (var_ref arg0)))))
+))
--- /dev/null
+((function faceforward
+ (signature float
+ (parameters
+ (declare (in) float N)
+ (declare (in) float I)
+ (declare (in) float Nref))
+ ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
+ ((return (var_ref N)))
+ ((return (expression float neg (var_ref N)))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 N)
+ (declare (in) vec2 I)
+ (declare (in) vec2 Nref))
+ ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
+ ((return (var_ref N)))
+ ((return (expression vec2 neg (var_ref N)))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 N)
+ (declare (in) vec3 I)
+ (declare (in) vec3 Nref))
+ ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
+ ((return (var_ref N)))
+ ((return (expression vec3 neg (var_ref N)))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 N)
+ (declare (in) vec4 I)
+ (declare (in) vec4 Nref))
+ ((if (expression bool < (expression float dot (var_ref Nref) (var_ref I)) (constant float (0)))
+ ((return (var_ref N)))
+ ((return (expression vec4 neg (var_ref N)))))))
+))
--- /dev/null
+((function floor
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float floor (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 floor (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 floor (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 floor (var_ref arg0)))))
+))
--- /dev/null
+((function fract
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (expression float - (var_ref x) (expression float floor (var_ref x))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((declare () vec2 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))
+ (return (var_ref t))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((declare () vec3 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))
+ (return (var_ref t))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((declare () vec4 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float - (swiz x (var_ref x)) (expression float floor (swiz x (var_ref x)))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float - (swiz y (var_ref x)) (expression float floor (swiz y (var_ref x)))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float - (swiz z (var_ref x)) (expression float floor (swiz z (var_ref x)))))
+ (assign (constant bool (1)) (swiz w (var_ref t)) (expression float - (swiz w (var_ref x)) (expression float floor (swiz w (var_ref x)))))
+ (return (var_ref t))))
+))
+
--- /dev/null
+((function greaterThan
+ (signature bvec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function greaterThanEqual
+ (signature bvec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function inversesqrt
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float rsq (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 rsq (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 rsq (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 rsq (var_ref arg0)))))
+))
--- /dev/null
+((function length
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
+
+ (signature float
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
+
+ (signature float
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
+
+ (signature float
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression float sqrt (expression float dot (var_ref arg0) (var_ref arg0))))))
+))
--- /dev/null
+((function lessThan
+ (signature bvec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function lessThanEqual
+ (signature bvec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function log
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float log (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 log (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 log (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 log (var_ref arg0)))))
+))
--- /dev/null
+((function log2
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float log2 (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 log2 (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 log2 (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 log2 (var_ref arg0)))))
+))
--- /dev/null
+((function matrixCompMult
+ (signature mat2
+ (parameters
+ (declare (in) mat2 x)
+ (declare (in) mat2 y))
+ ((declare () mat2 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+(return (var_ref z))))
+
+ (signature mat3
+ (parameters
+ (declare (in) mat3 x)
+ (declare (in) mat3 y))
+ ((declare () mat3 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
+(return (var_ref z))))
+
+ (signature mat4
+ (parameters
+ (declare (in) mat4 x)
+ (declare (in) mat4 y))
+ ((declare () mat4 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec4 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3)))))
+(return (var_ref z))))
+))
+
--- /dev/null
+((function max
+ (signature float
+ (parameters
+ (declare (in) float arg0)
+ (declare (in) float arg1))
+ ((return (expression float max (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((return (expression vec2 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((return (expression vec3 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((return (expression vec4 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) float arg1))
+ ((declare () vec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) float arg1))
+ ((declare () vec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) float arg1))
+ ((declare () vec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression float max (swiz z (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result))
+ (expression float max (swiz w (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+))
--- /dev/null
+((function min
+ (signature float
+ (parameters
+ (declare (in) float arg0)
+ (declare (in) float arg1))
+ ((return (expression float min (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((return (expression vec2 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((return (expression vec3 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((return (expression vec4 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) float arg1))
+ ((declare () vec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) float arg1))
+ ((declare () vec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) float arg1))
+ ((declare () vec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression float min (swiz z (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result))
+ (expression float min (swiz w (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+))
--- /dev/null
+((function mix
+ (signature float
+ (parameters
+ (declare (in) float arg0)
+ (declare (in) float arg1)
+ (declare (in) float arg2))
+ ((return (expression float + (expression float * (var_ref arg0) (expression float - (constant float (1.000000)) (var_ref arg2))) (expression float * (var_ref arg1) (var_ref arg2))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1)
+ (declare (in) vec2 arg2))
+ ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1)
+ (declare (in) vec3 arg2))
+ ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1)
+ (declare (in) vec4 arg2))
+ ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1)
+ (declare (in) float arg2))
+ ((return (expression vec2 + (expression vec2 * (var_ref arg0) (expression vec2 - (constant float (1.000000)) (var_ref arg2))) (expression vec2 * (var_ref arg1) (var_ref arg2))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1)
+ (declare (in) float arg2))
+ ((return (expression vec3 + (expression vec3 * (var_ref arg0) (expression vec3 - (constant float (1.000000)) (var_ref arg2))) (expression vec3 * (var_ref arg1) (var_ref arg2))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1)
+ (declare (in) float arg2))
+ ((return (expression vec4 + (expression vec4 * (var_ref arg0) (expression vec4 - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))
+))
--- /dev/null
+((function mod
+ (signature float
+ (parameters
+ (declare (in) float arg0)
+ (declare (in) float arg1))
+ ((return (expression float % (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((return (expression vec2 % (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((return (expression vec3 % (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((return (expression vec4 % (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) float arg1))
+ ((declare () vec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) float arg1))
+ ((declare () vec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) float arg1))
+ ((declare () vec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression float % (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression float % (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression float % (swiz z (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result))
+ (expression float % (swiz w (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+))
--- /dev/null
+((function noise1
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (constant float (0)))))
+ (signature float
+ (parameters
+ (declare (in) vec2 x))
+ ((return (constant float (0)))))
+ (signature float
+ (parameters
+ (declare (in) vec3 x))
+ ((return (constant float (0)))))
+ (signature float
+ (parameters
+ (declare (in) vec4 x))
+ ((return (constant float (0)))))
+ )
+
+ (function noise2
+ (signature vec2
+ (parameters
+ (declare (in) float x))
+ ((return (constant vec2 (0 0)))))
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((return (constant vec2 (0 0)))))
+ (signature vec2
+ (parameters
+ (declare (in) vec3 x))
+ ((return (constant vec2 (0 0)))))
+ (signature vec2
+ (parameters
+ (declare (in) vec4 x))
+ ((return (constant vec2 (0 0)))))
+ )
+
+ (function noise3
+ (signature vec3
+ (parameters
+ (declare (in) float x))
+ ((return (constant vec3 (0 0 0)))))
+ (signature vec3
+ (parameters
+ (declare (in) vec2 x))
+ ((return (constant vec3 (0 0 0)))))
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((return (constant vec3 (0 0 0)))))
+ (signature vec3
+ (parameters
+ (declare (in) vec4 x))
+ ((return (constant vec3 (0 0 0)))))
+ )
+
+ (function noise4
+ (signature vec4
+ (parameters
+ (declare (in) float x))
+ ((return (constant vec4 (0 0 0 0)))))
+ (signature vec4
+ (parameters
+ (declare (in) vec2 x))
+ ((return (constant vec4 (0 0 0 0)))))
+ (signature vec4
+ (parameters
+ (declare (in) vec3 x))
+ ((return (constant vec4 (0 0 0 0)))))
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((return (constant vec4 (0 0 0 0)))))
+ )
+)
--- /dev/null
+((function normalize
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 * (var_ref arg0) (expression float rsq (expression float dot (var_ref arg0) (var_ref arg0)))))))
+))
--- /dev/null
+((function not
+ (signature bvec2
+ (parameters
+ (declare (in) bvec2 arg0))
+ ((return (expression bvec2 ! (var_ref arg0)))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) bvec3 arg0))
+ ((return (expression bvec3 ! (var_ref arg0)))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) bvec4 arg0))
+ ((return (expression bvec4 ! (var_ref arg0)))))
+))
--- /dev/null
+((function notEqual
+ (signature bvec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression float != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression float != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression float != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression float != (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression int != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression int != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression int != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression int != (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function pow
+ (signature float
+ (parameters
+ (declare (in) float arg0)
+ (declare (in) float arg1))
+ ((return (expression float pow (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0)
+ (declare (in) vec2 arg1))
+ ((return (expression vec2 pow (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0)
+ (declare (in) vec3 arg1))
+ ((return (expression vec3 pow (var_ref arg0) (var_ref arg1)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0)
+ (declare (in) vec4 arg1))
+ ((return (expression vec4 pow (var_ref arg0) (var_ref arg1)))))
+))
--- /dev/null
+((function radians
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float * (var_ref arg0) (constant float (0.017453))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 * (var_ref arg0) (constant float (0.017453))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 * (var_ref arg0) (constant float (0.017453))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 * (var_ref arg0) (constant float (0.017453))))))
+))
--- /dev/null
+((function reflect
+ (signature float
+ (parameters
+ (declare (in) float i)
+ (declare (in) float n))
+ ((return (expression float -
+ (var_ref i)
+ (expression float *
+ (constant float (2.0))
+ (expression float *
+ (expression float dot
+ (var_ref n)
+ (var_ref i))
+ (var_ref n)))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 i)
+ (declare (in) vec2 n))
+ ((return (expression vec2 -
+ (var_ref i)
+ (expression vec2 *
+ (constant float (2.0))
+ (expression vec2 *
+ (expression float dot
+ (var_ref n)
+ (var_ref i))
+ (var_ref n)))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 i)
+ (declare (in) vec3 n))
+ ((return (expression vec3 -
+ (var_ref i)
+ (expression vec3 *
+ (constant float (2.0))
+ (expression vec3 *
+ (expression float dot
+ (var_ref n)
+ (var_ref i))
+ (var_ref n)))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 i)
+ (declare (in) vec4 n))
+ ((return (expression vec4 -
+ (var_ref i)
+ (expression vec4 *
+ (constant float (2.0))
+ (expression vec4 *
+ (expression float dot
+ (var_ref n)
+ (var_ref i))
+ (var_ref n)))))))
+
+))
--- /dev/null
+((function refract
+ (signature float
+ (parameters
+ (declare (in) float i)
+ (declare (in) float n)
+ (declare (in) float eta))
+ ((declare () float k)
+ (assign (constant bool (1)) (var_ref k)
+ (expression float - (constant float (1.0))
+ (expression float * (var_ref eta)
+ (expression float * (var_ref eta)
+ (expression float - (constant float (1.0))
+ (expression float *
+ (expression float dot (var_ref n) (var_ref i))
+ (expression float dot (var_ref n) (var_ref i))))))))
+ (if (expression bool < (var_ref k) (constant float (0.0)))
+ ((return (constant float (0.0))))
+ ((return (expression float -
+ (expression float * (var_ref eta) (var_ref i))
+ (expression float *
+ (expression float +
+ (expression float * (var_ref eta)
+ (expression float dot (var_ref n) (var_ref i)))
+ (expression float sqrt (var_ref k)))
+ (var_ref n))))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 i)
+ (declare (in) vec2 n)
+ (declare (in) float eta))
+ ((declare () float k)
+ (assign (constant bool (1)) (var_ref k)
+ (expression float - (constant float (1.0))
+ (expression float * (var_ref eta)
+ (expression float * (var_ref eta)
+ (expression float - (constant float (1.0))
+ (expression float *
+ (expression float dot (var_ref n) (var_ref i))
+ (expression float dot (var_ref n) (var_ref i))))))))
+ (if (expression bool < (var_ref k) (constant float (0.0)))
+ ((return (constant vec2 (0.0 0.0))))
+ ((return (expression vec2 -
+ (expression vec2 * (var_ref eta) (var_ref i))
+ (expression vec2 *
+ (expression float +
+ (expression float * (var_ref eta)
+ (expression float dot (var_ref n) (var_ref i)))
+ (expression float sqrt (var_ref k)))
+ (var_ref n))))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 i)
+ (declare (in) vec3 n)
+ (declare (in) float eta))
+ ((declare () float k)
+ (assign (constant bool (1)) (var_ref k)
+ (expression float - (constant float (1.0))
+ (expression float * (var_ref eta)
+ (expression float * (var_ref eta)
+ (expression float - (constant float (1.0))
+ (expression float *
+ (expression float dot (var_ref n) (var_ref i))
+ (expression float dot (var_ref n) (var_ref i))))))))
+ (if (expression bool < (var_ref k) (constant float (0.0)))
+ ((return (constant vec3 (0.0 0.0))))
+ ((return (expression vec3 -
+ (expression vec3 * (var_ref eta) (var_ref i))
+ (expression vec3 *
+ (expression float +
+ (expression float * (var_ref eta)
+ (expression float dot (var_ref n) (var_ref i)))
+ (expression float sqrt (var_ref k)))
+ (var_ref n))))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 i)
+ (declare (in) vec4 n)
+ (declare (in) float eta))
+ ((declare () float k)
+ (assign (constant bool (1)) (var_ref k)
+ (expression float - (constant float (1.0))
+ (expression float * (var_ref eta)
+ (expression float * (var_ref eta)
+ (expression float - (constant float (1.0))
+ (expression float *
+ (expression float dot (var_ref n) (var_ref i))
+ (expression float dot (var_ref n) (var_ref i))))))))
+ (if (expression bool < (var_ref k) (constant float (0.0)))
+ ((return (constant vec4 (0.0 0.0))))
+ ((return (expression vec4 -
+ (expression vec4 * (var_ref eta) (var_ref i))
+ (expression vec4 *
+ (expression float +
+ (expression float * (var_ref eta)
+ (expression float dot (var_ref n) (var_ref i)))
+ (expression float sqrt (var_ref k)))
+ (var_ref n))))))))
+
+))
--- /dev/null
+((function sign
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (expression float sign (var_ref x)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((declare () vec2 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))
+ (return (var_ref t))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((declare () vec3 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))
+ (return (var_ref t))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((declare () vec4 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float sign (swiz x (var_ref x))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float sign (swiz y (var_ref x))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float sign (swiz z (var_ref x))))
+ (assign (constant bool (1)) (swiz w (var_ref t)) (expression float sign (swiz w (var_ref x))))
+ (return (var_ref t))))
+))
+
--- /dev/null
+((function sin
+ (signature float
+ (parameters
+ (declare (in) float angle))
+ ((return (expression float sin (var_ref angle)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 angle))
+ ((return (expression vec2 sin (var_ref angle)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 angle))
+ ((return (expression vec3 sin (var_ref angle)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 angle))
+ ((return (expression vec4 sin (var_ref angle)))))
+))
--- /dev/null
+((function smoothstep
+ (signature float
+ (parameters
+ (declare (in) float edge0)
+ (declare (in) float edge1)
+ (declare (in) float x))
+ ((declare () float t)
+
+ (assign (constant bool (1)) (var_ref t)
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (var_ref x) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (return (expression float * (var_ref t) (expression float * (var_ref t) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (var_ref t))))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) float edge0)
+ (declare (in) float edge1)
+ (declare (in) vec2 x))
+ ((declare () vec2 t)
+ (declare () vec2 retval)
+
+ (assign (constant bool (1)) (swiz x (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz y (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
+ (return (var_ref retval))
+ ))
+
+ (signature vec3
+ (parameters
+ (declare (in) float edge0)
+ (declare (in) float edge1)
+ (declare (in) vec3 x))
+ ((declare () vec3 t)
+ (declare () vec3 retval)
+
+ (assign (constant bool (1)) (swiz x (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz y (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz z (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
+ (return (var_ref retval))
+ ))
+
+
+ (signature vec4
+ (parameters
+ (declare (in) float edge0)
+ (declare (in) float edge1)
+ (declare (in) vec4 x))
+ ((declare () vec4 t)
+ (declare () vec4 retval)
+
+ (assign (constant bool (1)) (swiz x (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz x (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz y (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz y (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz z (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz z (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz w (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz w (var_ref x)) (var_ref edge0)) (expression float - (var_ref edge1) (var_ref edge0)))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))
+ (return (var_ref retval))
+ ))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 edge0)
+ (declare (in) vec2 edge1)
+ (declare (in) vec2 x))
+ ((declare () vec2 t)
+ (declare () vec2 retval)
+
+ (assign (constant bool (1)) (swiz x (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz y (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
+ (return (var_ref retval))
+ ))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 edge0)
+ (declare (in) vec3 edge1)
+ (declare (in) vec3 x))
+ ((declare () vec3 t)
+ (declare () vec3 retval)
+
+ (assign (constant bool (1)) (swiz x (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz y (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz z (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
+ (return (var_ref retval))
+ ))
+
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 edge0)
+ (declare (in) vec4 edge1)
+ (declare (in) vec4 x))
+ ((declare () vec4 t)
+ (declare () vec4 retval)
+
+ (assign (constant bool (1)) (swiz x (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz x (var_ref x)) (swiz x (var_ref edge0))) (expression float - (swiz x (var_ref edge1)) (swiz x (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz x (var_ref retval)) (expression float * (swiz x (var_ref t)) (expression float * (swiz x (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz x (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz y (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz y (var_ref x)) (swiz y (var_ref edge0))) (expression float - (swiz y (var_ref edge1)) (swiz y (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz y (var_ref retval)) (expression float * (swiz y (var_ref t)) (expression float * (swiz y (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz y (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz z (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz z (var_ref x)) (swiz z (var_ref edge0))) (expression float - (swiz z (var_ref edge1)) (swiz z (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz z (var_ref retval)) (expression float * (swiz z (var_ref t)) (expression float * (swiz z (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz z (var_ref t)))))))
+
+ (assign (constant bool (1)) (swiz w (var_ref t))
+ (expression float max
+ (expression float min
+ (expression float / (expression float - (swiz w (var_ref x)) (swiz w (var_ref edge0))) (expression float - (swiz w (var_ref edge1)) (swiz w (var_ref edge0))))
+ (constant float (1.0)))
+ (constant float (0.0))))
+ (assign (constant bool (1)) (swiz w (var_ref retval)) (expression float * (swiz w (var_ref t)) (expression float * (swiz w (var_ref t)) (expression float - (constant float (3.000000)) (expression float * (constant float (2.000000)) (swiz w (var_ref t)))))))
+ (return (var_ref retval))
+ ))
+
+))
+
--- /dev/null
+((function sqrt
+ (signature float
+ (parameters
+ (declare (in) float arg0))
+ ((return (expression float sqrt (var_ref arg0)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 arg0))
+ ((return (expression vec2 sqrt (var_ref arg0)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 arg0))
+ ((return (expression vec3 sqrt (var_ref arg0)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 arg0))
+ ((return (expression vec4 sqrt (var_ref arg0)))))
+))
--- /dev/null
+((function step
+ (signature float
+ (parameters
+ (declare (in) float edge)
+ (declare (in) float x))
+ ((return (expression float b2f (expression bool < (var_ref x) (var_ref edge))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) float edge)
+ (declare (in) vec2 x))
+ ((declare () vec2 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))
+ (return (var_ref t))))
+
+ (signature vec3
+ (parameters
+ (declare (in) float edge)
+ (declare (in) vec3 x))
+ ((declare () vec3 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))
+ (return (var_ref t))))
+
+ (signature vec4
+ (parameters
+ (declare (in) float edge)
+ (declare (in) vec4 x))
+ ((declare () vec4 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(var_ref edge))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(var_ref edge))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(var_ref edge))))
+ (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(var_ref edge))))
+ (return (var_ref t))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 edge)
+ (declare (in) vec2 x))
+ ((declare () vec2 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))
+ (return (var_ref t))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 edge)
+ (declare (in) vec3 x))
+ ((declare () vec3 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz z (var_ref x))(swiz z (var_ref edge)))))
+ (return (var_ref t))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 edge)
+ (declare (in) vec4 x))
+ ((declare () vec4 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression float b2f (expression bool < (swiz x (var_ref x))(swiz x (var_ref edge)))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz y (var_ref edge)))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression float b2f (expression bool < (swiz y (var_ref x))(swiz z (var_ref edge)))))
+ (assign (constant bool (1)) (swiz w (var_ref t)) (expression float b2f (expression bool < (swiz w (var_ref x))(swiz w (var_ref edge)))))
+ (return (var_ref t))))
+))
+
--- /dev/null
+((function tan
+ (signature float
+ (parameters
+ (declare (in) float angle))
+ ((return (expression float / (expression float sin (var_ref angle)) (expression float cos (var_ref angle))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 angle))
+ ((return (expression float / (expression float sin (var_ref angle)) (expression vec2 cos (var_ref angle))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 angle))
+ ((return (expression float / (expression float sin (var_ref angle)) (expression vec3 cos (var_ref angle))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 angle))
+ ((return (expression float / (expression float sin (var_ref angle)) (expression vec4 cos (var_ref angle))))))
+))
--- /dev/null
+((function texture1D
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) float P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+)
+ (function texture1DLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+)
+ (function texture1DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+)
+ (function texture1DProjLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+)
+ (function texture2D
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+)
+(function texture2DLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+)
+ (function texture2DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+)
+ (function texture2DProjLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+)
+ (function texture3D
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+)
+ (function texture3DLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+)
+ (function texture3DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+)
+ (function texture3DProjLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+)
+ (function textureCube
+ (signature vec4
+ (parameters
+ (declare (in) samplerCube sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+)
+ (function textureCubeLod
+ (signature vec4
+ (parameters
+ (declare (in) samplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+)
+ (function shadow1D
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DShadow sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
+
+)
+ (function shadow1DLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DShadow sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))
+
+)
+ (function shadow1DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DShadow sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))
+
+)
+ (function shadow1DProjLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DShadow sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))
+
+)
+ (function shadow2D
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DShadow sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
+
+)
+ (function shadow2DLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DShadow sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))
+
+)
+ (function shadow2DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DShadow sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) ))))
+
+)
+ (function shadow2DProjLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DShadow sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref lod) ))))
+
+))
--- /dev/null
+((function dFdx
+ (signature float
+ (parameters
+ (declare (in) float p))
+ ((return (expression float dFdx (var_ref p)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 p))
+ ((return (expression vec2 dFdx (var_ref p)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 p))
+ ((return (expression vec3 dFdx (var_ref p)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 p))
+ ((return (expression vec4 dFdx (var_ref p)))))
+ )
+
+ (function dFdy
+ (signature float
+ (parameters
+ (declare (in) float p))
+ ((return (expression float dFdy (var_ref p)))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 p))
+ ((return (expression vec2 dFdy (var_ref p)))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 p))
+ ((return (expression vec3 dFdy (var_ref p)))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 p))
+ ((return (expression vec4 dFdy (var_ref p)))))
+ )
+
+ (function fwidth
+ (signature float
+ (parameters
+ (declare (in) float p))
+ ((return (expression float +
+ (expression float abs (expression float dFdx (var_ref p)))
+ (expression float abs (expression float dFdy (var_ref p)))))))
+
+ (signature vec2
+ (parameters
+ (declare (in) vec2 p))
+ ((return (expression vec2 +
+ (expression vec2 abs (expression vec2 dFdx (var_ref p)))
+ (expression vec2 abs (expression vec2 dFdy (var_ref p)))))))
+
+ (signature vec3
+ (parameters
+ (declare (in) vec3 p))
+ ((return (expression vec3 +
+ (expression vec3 abs (expression vec3 dFdx (var_ref p)))
+ (expression vec3 abs (expression vec3 dFdy (var_ref p)))))))
+
+ (signature vec4
+ (parameters
+ (declare (in) vec4 p))
+ ((return (expression vec4 +
+ (expression vec4 abs (expression vec4 dFdx (var_ref p)))
+ (expression vec4 abs (expression vec4 dFdy (var_ref p)))))))
+))
--- /dev/null
+((function texture1D
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+)
+ (function texture1DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+)
+ (function texture2D
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+)
+ (function texture2DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+)
+ (function texture3D
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+)
+ (function texture3DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+)
+ (function textureCube
+ (signature vec4
+ (parameters
+ (declare (in) samplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+)
+ (function shadow1D
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DShadow sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))
+
+)
+ (function shadow1DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DShadow sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))
+
+)
+ (function shadow2D
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DShadow sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))
+
+)
+ (function shadow2DProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DShadow sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) (swiz z (var_ref P)) (var_ref bias) ))))
+
+))
--- /dev/null
+((function ftransform
+ (signature vec4
+ (parameters)
+ ((return (expression vec4 *
+ (var_ref gl_ModelViewProjectionMatrix)
+ (var_ref gl_Vertex)))))
+))
--- /dev/null
+((function matrixCompMult
+ (signature mat2x3
+ (parameters
+ (declare (in) mat2x3 x)
+ (declare (in) mat2x3 y))
+ ((declare () mat2x3 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+(return (var_ref z))))
+
+ (signature mat3x2
+ (parameters
+ (declare (in) mat3x2 x)
+ (declare (in) mat3x2 y))
+ ((declare () mat3x2 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
+(return (var_ref z))))
+
+ (signature mat2x4
+ (parameters
+ (declare (in) mat2x4 x)
+ (declare (in) mat2x4 y))
+ ((declare () mat2x4 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+(return (var_ref z))))
+
+ (signature mat4x2
+ (parameters
+ (declare (in) mat4x2 x)
+ (declare (in) mat4x2 y))
+ ((declare () mat4x2 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec2 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec2 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec2 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec2 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3)))))
+(return (var_ref z))))
+
+ (signature mat3x4
+ (parameters
+ (declare (in) mat3x4 x)
+ (declare (in) mat3x4 y))
+ ((declare () mat3x4 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec4 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec4 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec4 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
+(return (var_ref z))))
+
+ (signature mat4x3
+ (parameters
+ (declare (in) mat4x3 x)
+ (declare (in) mat4x3 y))
+ ((declare () mat4x3 z)
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (0))) (expression vec3 * (array_ref (var_ref x) (constant int (0))) (array_ref (var_ref y) (constant int (0)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (1))) (expression vec3 * (array_ref (var_ref x) (constant int (1))) (array_ref (var_ref y) (constant int (1)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (2))) (expression vec3 * (array_ref (var_ref x) (constant int (2))) (array_ref (var_ref y) (constant int (2)))))
+ (assign (constant bool (1)) (array_ref (var_ref z) (constant int (3))) (expression vec3 * (array_ref (var_ref x) (constant int (3))) (array_ref (var_ref y) (constant int (3)))))
+(return (var_ref z))))
+))
--- /dev/null
+((function outerProduct
+ (signature mat2
+ (parameters
+ (declare (in) vec2 u)
+ (declare (in) vec2 v))
+ ((declare () mat2 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat2x3
+ (parameters
+ (declare (in) vec2 u)
+ (declare (in) vec3 v))
+ ((declare () mat2x3 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat2x4
+ (parameters
+ (declare (in) vec2 u)
+ (declare (in) vec4 v))
+ ((declare () mat2x4 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat3x2
+ (parameters
+ (declare (in) vec3 u)
+ (declare (in) vec2 v))
+ ((declare () mat3x2 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat3
+ (parameters
+ (declare (in) vec3 u)
+ (declare (in) vec3 v))
+ ((declare () mat3 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat3x4
+ (parameters
+ (declare (in) vec3 u)
+ (declare (in) vec4 v))
+ ((declare () mat3x4 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat4x2
+ (parameters
+ (declare (in) vec4 u)
+ (declare (in) vec2 v))
+ ((declare () mat4x2 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref v) (swiz y (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref v) (swiz z (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec2 * (var_ref v) (swiz w (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat4x3
+ (parameters
+ (declare (in) vec4 u)
+ (declare (in) vec3 v))
+ ((declare () mat4x3 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref v) (swiz y (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref v) (swiz z (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec3 * (var_ref v) (swiz w (var_ref u))))
+(return (var_ref m))))
+
+ (signature mat4
+ (parameters
+ (declare (in) vec4 u)
+ (declare (in) vec4 v))
+ ((declare () mat4 m)
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref v) (swiz x (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref v) (swiz y (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref v) (swiz z (var_ref u))))
+ (assign (constant bool (1)) (array_ref (var_ref m) (constant int (3))) (expression vec4 * (var_ref v) (swiz w (var_ref u))))
+(return (var_ref m))))
+))
+
--- /dev/null
+((function transpose
+ (signature mat2
+ (parameters
+ (declare (in) mat2 m))
+ ((declare () mat2 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+(return (var_ref t))))
+
+ (signature mat3x2
+ (parameters
+ (declare (in) mat2x3 m))
+ ((declare () mat3x2 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
+(return (var_ref t))))
+
+ (signature mat4x2
+ (parameters
+ (declare (in) mat2x4 m))
+ ((declare () mat4x2 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1)))))
+(return (var_ref t))))
+
+ (signature mat2x3
+ (parameters
+ (declare (in) mat3x2 m))
+ ((declare () mat2x3 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
+(return (var_ref t))))
+
+ (signature mat3
+ (parameters
+ (declare (in) mat3 m))
+ ((declare () mat3 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
+(return (var_ref t))))
+
+ (signature mat4x3
+ (parameters
+ (declare (in) mat3x4 m))
+ ((declare () mat4x3 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2)))))
+(return (var_ref t))))
+
+ (signature mat2x4
+ (parameters
+ (declare (in) mat4x2 m))
+ ((declare () mat2x4 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3)))))
+(return (var_ref t))))
+
+ (signature mat3x4
+ (parameters
+ (declare (in) mat4x3 m))
+ ((declare () mat3x4 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3)))))
+(return (var_ref t))))
+
+ (signature mat4
+ (parameters
+ (declare (in) mat4 m))
+ ((declare () mat4 t)
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz x (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (0)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz y (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (1)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz z (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (2)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (0)))) (swiz x (array_ref (var_ref m) (constant int (3)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (1)))) (swiz y (array_ref (var_ref m) (constant int (3)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (2)))) (swiz z (array_ref (var_ref m) (constant int (3)))))
+ (assign (constant bool (1)) (swiz w (array_ref (var_ref t) (constant int (3)))) (swiz w (array_ref (var_ref m) (constant int (3)))))
+(return (var_ref t))))
+)
+
+)
+
--- /dev/null
+((function clamp
+ (signature int
+ (parameters
+ (declare (in) int arg0)
+ (declare (in) int arg1)
+ (declare (in) int arg2))
+ ((return (expression int max (expression int min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature ivec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1)
+ (declare (in) ivec2 arg2))
+ ((return (expression ivec2 max (expression ivec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature ivec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1)
+ (declare (in) ivec3 arg2))
+ ((return (expression ivec3 max (expression ivec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1)
+ (declare (in) ivec4 arg2))
+ ((return (expression ivec4 max (expression ivec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature ivec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) int arg1)
+ (declare (in) int arg2))
+ ((declare () ivec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature ivec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) int arg1)
+ (declare (in) int arg2))
+ ((declare () ivec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) int arg1)
+ (declare (in) int arg2))
+ ((declare () ivec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result)) (expression ivec4 max (expression ivec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uint
+ (parameters
+ (declare (in) uint arg0)
+ (declare (in) uint arg1)
+ (declare (in) uint arg2))
+ ((return (expression uint max (expression uint min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature uvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1)
+ (declare (in) uvec2 arg2))
+ ((return (expression uvec2 max (expression uvec2 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature uvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1)
+ (declare (in) uvec3 arg2))
+ ((return (expression uvec3 max (expression uvec3 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1)
+ (declare (in) uvec4 arg2))
+ ((return (expression uvec4 max (expression uvec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))
+
+ (signature uvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uint arg1)
+ (declare (in) uint arg2))
+ ((declare () uvec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uint arg1)
+ (declare (in) uint arg2))
+ ((declare () uvec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uint arg1)
+ (declare (in) uint arg2))
+ ((declare () uvec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz x (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz y (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz z (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result)) (expression uvec4 max (expression uvec4 min (swiz w (var_ref arg0)) (var_ref arg2)) (var_ref arg1)))
+ (return (var_ref result))))
+))
--- /dev/null
+((function cosh
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (expression float * (constant float (0.5))
+ (expression float +
+ (expression float exp (var_ref x))
+ (expression float exp (expression float neg (var_ref x))))))))
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((return (expression vec2 * (constant vec2 (0.5))
+ (expression vec2 +
+ (expression vec2 exp (var_ref x))
+ (expression vec2 exp (expression vec2 neg (var_ref x))))))))
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((return (expression vec3 * (constant vec3 (0.5))
+ (expression vec3 +
+ (expression vec3 exp (var_ref x))
+ (expression vec3 exp (expression vec3 neg (var_ref x))))))))
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((return (expression vec4 * (constant vec4 (0.5))
+ (expression vec4 +
+ (expression vec4 exp (var_ref x))
+ (expression vec4 exp (expression vec4 neg (var_ref x))))))))
+))
--- /dev/null
+((function equal
+ (signature bvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool == (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool == (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool == (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool == (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function greaterThan
+ (signature bvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool > (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool > (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool > (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool > (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function greaterThanEqual
+ (signature bvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool >= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool >= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool >= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool >= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function lessThan
+ (signature bvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool < (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool < (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool < (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool < (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function lessThanEqual
+ (signature bvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool <= (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool <= (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool <= (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool <= (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function max
+ (signature int
+ (parameters
+ (declare (in) int arg0)
+ (declare (in) int arg1))
+ ((return (expression int max (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((return (expression ivec2 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((return (expression ivec3 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((return (expression ivec4 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) int arg1))
+ ((declare () ivec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature ivec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) int arg1))
+ ((declare () ivec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) int arg1))
+ ((declare () ivec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression int max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression int max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression int max (swiz z (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result))
+ (expression int max (swiz w (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uint
+ (parameters
+ (declare (in) uint arg0)
+ (declare (in) uint arg1))
+ ((return (expression uint max (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((return (expression uvec2 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((return (expression uvec3 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((return (expression uvec4 max (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uint arg1))
+ ((declare () uvec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uint arg1))
+ ((declare () uvec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uint arg1))
+ ((declare () uvec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression uint max (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression uint max (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression uint max (swiz z (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result))
+ (expression uint max (swiz w (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+))
--- /dev/null
+((function min
+ (signature int
+ (parameters
+ (declare (in) int arg0)
+ (declare (in) int arg1))
+ ((return (expression int min (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) ivec2 arg1))
+ ((return (expression ivec2 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) ivec3 arg1))
+ ((return (expression ivec3 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) ivec4 arg1))
+ ((return (expression ivec4 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature ivec2
+ (parameters
+ (declare (in) ivec2 arg0)
+ (declare (in) int arg1))
+ ((declare () ivec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature ivec3
+ (parameters
+ (declare (in) ivec3 arg0)
+ (declare (in) int arg1))
+ ((declare () ivec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) ivec4 arg0)
+ (declare (in) int arg1))
+ ((declare () ivec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression int min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression int min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression int min (swiz z (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result))
+ (expression int min (swiz w (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uint
+ (parameters
+ (declare (in) uint arg0)
+ (declare (in) uint arg1))
+ ((return (expression uint min (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((return (expression uvec2 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((return (expression uvec3 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((return (expression uvec4 min (var_ref arg0) (var_ref arg1)))))
+
+ (signature uvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uint arg1))
+ ((declare () uvec2 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uint arg1))
+ ((declare () uvec3 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uint arg1))
+ ((declare () uvec4 result)
+ (assign (constant bool (1)) (swiz x (var_ref result))
+ (expression uint min (swiz x (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz y (var_ref result))
+ (expression uint min (swiz y (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz z (var_ref result))
+ (expression uint min (swiz z (var_ref arg0)) (var_ref arg1)))
+ (assign (constant bool (1)) (swiz w (var_ref result))
+ (expression uint min (swiz w (var_ref arg0)) (var_ref arg1)))
+ (return (var_ref result))))
+))
--- /dev/null
+((function notEqual
+ (signature bvec2
+ (parameters
+ (declare (in) uvec2 arg0)
+ (declare (in) uvec2 arg1))
+ ((declare () bvec2 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec3
+ (parameters
+ (declare (in) uvec3 arg0)
+ (declare (in) uvec3 arg1))
+ ((declare () bvec3 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (return (var_ref temp))))
+
+ (signature bvec4
+ (parameters
+ (declare (in) uvec4 arg0)
+ (declare (in) uvec4 arg1))
+ ((declare () bvec4 temp)
+ (assign (constant bool (1)) (swiz x (var_ref temp)) (expression bool != (swiz x (var_ref arg0))(swiz x (var_ref arg1))))
+ (assign (constant bool (1)) (swiz y (var_ref temp)) (expression bool != (swiz y (var_ref arg0))(swiz y (var_ref arg1))))
+ (assign (constant bool (1)) (swiz z (var_ref temp)) (expression bool != (swiz z (var_ref arg0))(swiz z (var_ref arg1))))
+ (assign (constant bool (1)) (swiz w (var_ref temp)) (expression bool != (swiz w (var_ref arg0))(swiz w (var_ref arg1))))
+ (return (var_ref temp))))
+))
--- /dev/null
+((function sign
+ (signature int
+ (parameters
+ (declare (in) int x))
+ ((return (expression int / (var_ref x) (expression int abs (var_ref x))))))
+
+ (signature ivec2
+ (parameters
+ (declare (in) ivec2 x))
+ ((declare () ivec2 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))
+ (return (var_ref t))))
+
+ (signature ivec3
+ (parameters
+ (declare (in) ivec3 x))
+ ((declare () ivec3 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))
+ (return (var_ref t))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) ivec4 x))
+ ((declare () ivec4 t)
+ (assign (constant bool (1)) (swiz x (var_ref t)) (expression int sign (swiz x (var_ref x))))
+ (assign (constant bool (1)) (swiz y (var_ref t)) (expression int sign (swiz y (var_ref x))))
+ (assign (constant bool (1)) (swiz z (var_ref t)) (expression int sign (swiz z (var_ref x))))
+ (assign (constant bool (1)) (swiz w (var_ref t)) (expression int sign (swiz w (var_ref x))))
+ (return (var_ref t))))
+))
+
--- /dev/null
+((function sinh
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (expression float * (constant float (0.5))
+ (expression float -
+ (expression float exp (var_ref x))
+ (expression float exp (expression float neg (var_ref x))))))))
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((return (expression vec2 * (constant vec2 (0.5))
+ (expression vec2 -
+ (expression vec2 exp (var_ref x))
+ (expression vec2 exp (expression vec2 neg (var_ref x))))))))
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((return (expression vec3 * (constant vec3 (0.5))
+ (expression vec3 -
+ (expression vec3 exp (var_ref x))
+ (expression vec3 exp (expression vec3 neg (var_ref x))))))))
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((return (expression vec4 * (constant vec4 (0.5))
+ (expression vec4 -
+ (expression vec4 exp (var_ref x))
+ (expression vec4 exp (expression vec4 neg (var_ref x))))))))
+))
--- /dev/null
+((function tanh
+ (signature float
+ (parameters
+ (declare (in) float x))
+ ((return (expression float /
+ (expression float -
+ (expression float exp (var_ref x))
+ (expression float exp (expression float neg (var_ref x))))
+ (expression float +
+ (expression float exp (var_ref x))
+ (expression float exp (expression float neg (var_ref x))))))))
+ (signature vec2
+ (parameters
+ (declare (in) vec2 x))
+ ((return (expression vec2 /
+ (expression vec2 -
+ (expression vec2 exp (var_ref x))
+ (expression vec2 exp (expression vec2 neg (var_ref x))))
+ (expression vec2 +
+ (expression vec2 exp (var_ref x))
+ (expression vec2 exp (expression vec2 neg (var_ref x))))))))
+ (signature vec3
+ (parameters
+ (declare (in) vec3 x))
+ ((return (expression vec3 /
+ (expression vec3 -
+ (expression vec3 exp (var_ref x))
+ (expression vec3 exp (expression vec3 neg (var_ref x))))
+ (expression vec3 +
+ (expression vec3 exp (var_ref x))
+ (expression vec3 exp (expression vec3 neg (var_ref x))))))))
+ (signature vec4
+ (parameters
+ (declare (in) vec4 x))
+ ((return (expression vec4 /
+ (expression vec4 -
+ (expression vec4 exp (var_ref x))
+ (expression vec4 exp (expression vec4 neg (var_ref x))))
+ (expression vec4 +
+ (expression vec4 exp (var_ref x))
+ (expression vec4 exp (expression vec4 neg (var_ref x))))))))
+))
--- /dev/null
+((function texelFetch
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) int P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) int P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) int P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) ivec2 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) ivec2 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) ivec2 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) ivec3 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) ivec3 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) ivec3 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) ivec2 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1DArray sampler)
+ (declare (in) ivec2 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1DArray sampler)
+ (declare (in) ivec2 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) ivec3 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2DArray sampler)
+ (declare (in) ivec3 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2DArray sampler)
+ (declare (in) ivec3 P)
+ (declare (in) int lod) )
+ ((return (txf (var_ref sampler) (var_ref P) (0 0 0) (var_ref lod) ))))
+
+))
--- /dev/null
+((function texture
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) float P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) float P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) float P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) samplerCube sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isamplerCube sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usamplerCube sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1DArray sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1DArray sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2DArray sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2DArray sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+))
--- /dev/null
+((function textureGrad
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) samplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isamplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usamplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (var_ref P) (0 0 0) 1 () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+)
+)
--- /dev/null
+((function textureLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) samplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isamplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usamplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+))
--- /dev/null
+((function textureProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ))))
+
+))
--- /dev/null
+((function textureLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float dPdx)
+ (declare (in) float dPdy) )
+ ((return (txd (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) vec2 dPdx)
+ (declare (in) vec2 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) vec3 dPdx)
+ (declare (in) vec3 dPdy) )
+ ((return (txd (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () ((var_ref dPdx) (var_ref dPdy)) ))))
+
+))
--- /dev/null
+((function textureLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref lod) ))))
+
+))
--- /dev/null
+((function texture
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) float P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) samplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isamplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usamplerCube sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+))
--- /dev/null
+((function textureProj
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz y (var_ref P)) () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler1D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz x (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz z (var_ref P)) () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler2D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature vec4
+ (parameters
+ (declare (in) sampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature ivec4
+ (parameters
+ (declare (in) isampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+ (signature uvec4
+ (parameters
+ (declare (in) usampler3D sampler)
+ (declare (in) vec4 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) (swiz w (var_ref P)) () (var_ref bias) ))))
+
+))
--- /dev/null
+((function texture2DRect
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DRect sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+)
+ (function shadow2DRect
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DRectShadow sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
+
+))
--- /dev/null
+((function texture1DArray
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) vec2 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+)
+ (function texture1DArrayLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+)
+ (function texture2DArray
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (var_ref P) (0 0 0) 1 () ))))
+
+)
+ (function texture2DArrayLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref lod) ))))
+
+)
+ (function shadow1DArray
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArrayShadow sampler)
+ (declare (in) vec3 P) )
+ ((return (tex (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) ))))
+
+)
+ (function shadow1DArrayLod
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArrayShadow sampler)
+ (declare (in) vec3 P)
+ (declare (in) float lod) )
+ ((return (txl (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref lod) ))))
+
+)
+ (function shadow2DArray
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArrayShadow sampler)
+ (declare (in) vec4 P) )
+ ((return (tex (var_ref sampler) (swiz xyz (var_ref P)) (0 0 0) 1 (swiz w (var_ref P)) ))))
+
+))
--- /dev/null
+((function texture1DArray
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArray sampler)
+ (declare (in) vec2 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+)
+ (function texture2DArray
+ (signature vec4
+ (parameters
+ (declare (in) sampler2DArray sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (var_ref P) (0 0 0) 1 () (var_ref bias) ))))
+
+)
+ (function shadow1DArray
+ (signature vec4
+ (parameters
+ (declare (in) sampler1DArrayShadow sampler)
+ (declare (in) vec3 P)
+ (declare (in) float bias) )
+ ((return (txb (var_ref sampler) (swiz xy (var_ref P)) (0 0 0) 1 (swiz z (var_ref P)) (var_ref bias) ))))
+
+))
--- /dev/null
+#!/usr/bin/env perl
+
+sub process_version {
+ my ($version) = @_;
+ my @vars;
+ print "/* $version builtins */\n\n";
+
+ my @files = <builtins/$version/*>;
+ foreach $file (@files) {
+ push(@vars, process_file($file));
+ }
+
+ print "static const char *functions_for_$version [] = {\n";
+ foreach $var (@vars) {
+ print " $var,\n";
+ }
+ print "};\n\n"
+}
+
+sub process_file {
+ my ($file) = @_;
+
+ # Change from builtins/110/foo to builtins_110_foo
+ my $var = $file; $var =~ s!/!_!g;
+
+ print "static const char *$var = {\n";
+ open SRC, "<", "$file" or die $!;
+ while (<SRC>) {
+ s/\\/\\\\/g;
+ s/\"/\\\"/g;
+ s/\n/\\n/g;
+ print " \"$_\"\n";
+ }
+ print "};\n\n";
+ close SRC or die $!;
+ return $var;
+}
+
+print << 'EOF';
+/* DO NOT MODIFY - automatically generated by generate_builtins.pl */
+/*
+ * 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 <stdio.h>
+#include "glsl_parser_extras.h"
+#include "ir_reader.h"
+
+void
+read_builtins(_mesa_glsl_parse_state *st, exec_list *instructions,
+ const char **functions, unsigned count)
+{
+ if (st->error)
+ return;
+
+ for (unsigned i = 0; i < count; i++) {
+ _mesa_glsl_read_ir(st, instructions, functions[i]);
+
+ if (st->error) {
+ printf("error reading builtin: %.35s ...\n", functions[i]);
+ return;
+ }
+ }
+}
+
+EOF
+
+@versions = sort(<builtins/[1-9A-Z]*>);
+foreach $version (@versions) {
+ $version =~ s!builtins/!!g;
+ process_version($version);
+}
+
+print << 'EOF';
+void
+_mesa_glsl_initialize_functions(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+EOF
+
+foreach $version_xs (@versions) {
+ $check = "";
+ if ($version_xs =~ /_vs/) {
+ $check = "state->target == vertex_shader && ";
+ } elsif ($version_xs =~ /_fs/) {
+ $check = "state->target == fragment_shader && ";
+ }
+ $version = $version_xs;
+ $version =~ s/_[vf]s//g;
+
+ if ($version =~ /^[1-9][0-9][0-9]/) {
+ $check = "${check}state->language_version >= $version";
+ } else {
+ # Not a version...an extension name
+ $check = "${check}state->${version}_enable";
+ }
+ print " if ($check)\n";
+ print " read_builtins(state, instructions,\n";
+ print " functions_for_$version_xs,\n";
+ print " sizeof(functions_for_$version_xs) / ";
+ print "sizeof(const char *));\n\n"
+}
+
+print "}\n";
--- /dev/null
+#!/usr/bin/python
+
+def gen_matrix(x, y = 0):
+ if y == 0:
+ y = x
+ type = "mat" + str(x)
+ if x != y:
+ type = type + "x" + str(y)
+ print type + " matrixCompMult(" + type + " x, " + type + " y)\n{"
+ print " " + type + " z;"
+
+ for i in range(x):
+ print " z[" + str(i) + "] = x[" + str(i) + "] * y[" + str(i) + "];"
+ print " return z;\n}"
+
+print "#version 120"
+# 1.10
+gen_matrix(2)
+gen_matrix(3)
+gen_matrix(4)
+
+# 1.20
+gen_matrix(2,3) # mat2x3 means 2 columns, 3 rows
+gen_matrix(3,2)
+gen_matrix(2,4)
+gen_matrix(4,2)
+gen_matrix(3,4)
+gen_matrix(4,3)
--- /dev/null
+#!/usr/bin/python
+
+def gen(x, y):
+ type = "mat" + str(x)
+ if x != y:
+ type = type + "x" + str(y)
+ print type + " outerProduct(vec" + str(x) + " u, vec" + str(y) + " v)\n{"
+ print " " + type + " m;"
+
+ for i in range(x):
+ print " m[" + str(i) + "] = v * u[" + str(i) + "];"
+ print " return m;\n}"
+
+print "#version 120"
+gen(2,2)
+gen(2,3) # mat2x3 means 2 columns, 3 rows
+gen(2,4)
+gen(3,2)
+gen(3,3)
+gen(3,4)
+gen(4,2)
+gen(4,3)
+gen(4,4)
--- /dev/null
+#!/usr/bin/python
+
+def gen(x, y):
+ origtype = "mat" + str(x)
+ trantype = "mat" + str(y)
+ if x != y:
+ origtype = origtype + "x" + str(y)
+ trantype = trantype + "x" + str(x)
+ print trantype + " transpose(" + origtype + " m)\n{"
+ print " " + trantype + " t;"
+
+ # The obvious implementation of transpose
+ for i in range(x):
+ for j in range(y):
+ print " t[" + str(j) + "][" + str(i) + "] =",
+ print "m[" + str(i) + "][" + str(j) + "];"
+ print " return t;\n}"
+
+print "#version 120"
+gen(2,2)
+gen(2,3) # mat2x3 means 2 columns, 3 rows
+gen(2,4)
+gen(3,2)
+gen(3,3)
+gen(3,4)
+gen(4,2)
+gen(4,3)
+gen(4,4)
--- /dev/null
+#!/usr/bin/python
+
+from os import path
+import sys
+
+def vec_type(g, size):
+ if size == 1:
+ if g == "i":
+ return "int"
+ elif g == "u":
+ return "uint"
+ return "float"
+ return g + "vec" + str(size)
+
+# Get the base dimension - i.e. sampler3D gives 3
+# Array samplers also get +1 here since the layer is really an extra coordinate
+def get_coord_dim(sampler_type):
+ if sampler_type[0].isdigit():
+ coord_dim = int(sampler_type[0])
+ elif sampler_type.startswith("Cube"):
+ coord_dim = 3
+ else:
+ assert False ("coord_dim: invalid sampler_type: " + sampler_type)
+
+ if sampler_type.find("Array") != -1:
+ coord_dim += 1
+ return coord_dim
+
+# Get the number of extra vector components (i.e. shadow comparitor)
+def get_extra_dim(sampler_type, use_proj, unused_fields):
+ extra_dim = unused_fields
+ if sampler_type.find("Shadow") != -1:
+ extra_dim += 1
+ if use_proj:
+ extra_dim += 1
+ return extra_dim
+
+def generate_sigs(g, tex_inst, sampler_type, use_proj = False, unused_fields = 0):
+ coord_dim = get_coord_dim(sampler_type)
+ extra_dim = get_extra_dim(sampler_type, use_proj, unused_fields)
+
+ # Print parameters
+ print " (signature " + g + "vec4"
+ print " (parameters"
+ print " (declare (in) " + g + "sampler" + sampler_type + " sampler)"
+ print " (declare (in) " + vec_type("i" if tex_inst == "txf" else "", coord_dim + extra_dim) + " P)",
+ if tex_inst == "txb":
+ print "\n (declare (in) float bias)",
+ elif tex_inst == "txl":
+ print "\n (declare (in) float lod)",
+ elif tex_inst == "txf":
+ print "\n (declare (in) int lod)",
+ elif tex_inst == "txd":
+ grad_type = vec_type("", coord_dim)
+ print "\n (declare (in) " + grad_type + " dPdx)",
+ print "\n (declare (in) " + grad_type + " dPdy)",
+
+ print ")\n ((return (" + tex_inst + " (var_ref sampler)",
+
+ # Coordinate
+ if extra_dim > 0:
+ print "(swiz " + "xyzw"[:coord_dim] + " (var_ref P))",
+ else:
+ print "(var_ref P)",
+
+ # Offset
+ print "(0 0 0)",
+
+ if tex_inst != "txf":
+ # Projective divisor
+ if use_proj:
+ print "(swiz " + "xyzw"[coord_dim + extra_dim-1] + " (var_ref P))",
+ else:
+ print "1",
+
+ # Shadow comparitor
+ if sampler_type == "2DArrayShadow": # a special case:
+ print "(swiz w (var_ref P))", # ...array layer is z; shadow is w
+ elif sampler_type.endswith("Shadow"):
+ print "(swiz z (var_ref P))",
+ else:
+ print "()",
+
+ # Bias/explicit LOD/gradient:
+ if tex_inst == "txb":
+ print "(var_ref bias)",
+ elif tex_inst == "txl" or tex_inst == "txf":
+ print "(var_ref lod)",
+ elif tex_inst == "txd":
+ print "((var_ref dPdx) (var_ref dPdy))",
+ print "))))\n"
+
+def generate_fiu_sigs(tex_inst, sampler_type, use_proj = False, unused_fields = 0):
+ generate_sigs("", tex_inst, sampler_type, use_proj, unused_fields)
+ generate_sigs("i", tex_inst, sampler_type, use_proj, unused_fields)
+ generate_sigs("u", tex_inst, sampler_type, use_proj, unused_fields)
+
+builtins_dir = path.join(path.dirname(path.abspath(__file__)), "..")
+
+with open(path.join(builtins_dir, "130", "texture"), 'w') as sys.stdout:
+ print "((function texture"
+ generate_fiu_sigs("tex", "1D")
+ generate_fiu_sigs("tex", "2D")
+ generate_fiu_sigs("tex", "3D")
+ generate_fiu_sigs("tex", "Cube")
+ generate_fiu_sigs("tex", "1DArray")
+ generate_fiu_sigs("tex", "2DArray")
+ print "))"
+
+# txb variants are only allowed within a fragment shader (GLSL 1.30 p. 86)
+with open(path.join(builtins_dir, "130_fs", "texture"), 'w') as sys.stdout:
+ print "((function texture"
+ generate_fiu_sigs("txb", "1D")
+ generate_fiu_sigs("txb", "2D")
+ generate_fiu_sigs("txb", "3D")
+ generate_fiu_sigs("txb", "Cube")
+ generate_fiu_sigs("txb", "1DArray")
+ generate_fiu_sigs("txb", "2DArray")
+ print "))"
+
+with open(path.join(builtins_dir, "130", "textureProj"), 'w') as sys.stdout:
+ print "((function textureProj"
+ generate_fiu_sigs("tex", "1D", True)
+ generate_fiu_sigs("tex", "1D", True, 2)
+ generate_fiu_sigs("tex", "2D", True)
+ generate_fiu_sigs("tex", "2D", True, 1)
+ generate_fiu_sigs("tex", "3D", True)
+ print "))"
+
+with open(path.join(builtins_dir, "130_fs", "textureProj"), 'w') as sys.stdout:
+ print "((function textureProj"
+ generate_fiu_sigs("txb", "1D", True)
+ generate_fiu_sigs("txb", "1D", True, 2)
+ generate_fiu_sigs("txb", "2D", True)
+ generate_fiu_sigs("txb", "2D", True, 1)
+ generate_fiu_sigs("txb", "3D", True)
+ print "))"
+
+with open(path.join(builtins_dir, "130", "textureLod"), 'w') as sys.stdout:
+ print "((function textureLod"
+ generate_fiu_sigs("txl", "1D")
+ generate_fiu_sigs("txl", "2D")
+ generate_fiu_sigs("txl", "3D")
+ generate_fiu_sigs("txl", "Cube")
+ generate_fiu_sigs("txl", "1DArray")
+ generate_fiu_sigs("txl", "2DArray")
+ print "))"
+
+with open(path.join(builtins_dir, "130", "texelFetch"), 'w') as sys.stdout:
+ print "((function texelFetch"
+ generate_fiu_sigs("txf", "1D")
+ generate_fiu_sigs("txf", "2D")
+ generate_fiu_sigs("txf", "3D")
+ generate_fiu_sigs("txf", "1DArray")
+ generate_fiu_sigs("txf", "2DArray")
+ print "))"
+
+with open(path.join(builtins_dir, "130", "textureProjLod"), 'w') as sys.stdout:
+ print "((function textureLod"
+ generate_fiu_sigs("txl", "1D", True)
+ generate_fiu_sigs("txl", "1D", True, 2)
+ generate_fiu_sigs("txl", "2D", True)
+ generate_fiu_sigs("txl", "2D", True, 1)
+ generate_fiu_sigs("txl", "3D", True)
+ print "))"
+
+with open(path.join(builtins_dir, "130", "textureGrad"), 'w') as sys.stdout:
+ print "((function textureGrad"
+ generate_fiu_sigs("txd", "1D")
+ generate_fiu_sigs("txd", "2D")
+ generate_fiu_sigs("txd", "3D")
+ generate_fiu_sigs("txd", "Cube")
+ generate_fiu_sigs("txd", "1DArray")
+ generate_fiu_sigs("txd", "2DArray")
+ print ")\n)"
+
+with open(path.join(builtins_dir, "130", "textureProjGrad"), 'w') as sys.stdout:
+ print "((function textureLod"
+ generate_fiu_sigs("txd", "1D", True)
+ generate_fiu_sigs("txd", "1D", True, 2)
+ generate_fiu_sigs("txd", "2D", True)
+ generate_fiu_sigs("txd", "2D", True, 1)
+ generate_fiu_sigs("txd", "3D", True)
+ print "))"
+
+# ARB_texture_rectangle extension
+with open(path.join(builtins_dir, "ARB_texture_rectangle", "textures"), 'w') as sys.stdout:
+ print "((function texture2DRect"
+ generate_sigs("", "tex", "2DRect")
+ print ")\n (function shadow2DRect"
+ generate_sigs("", "tex", "2DRectShadow")
+ print "))"
+
+# EXT_texture_array extension
+with open(path.join(builtins_dir, "EXT_texture_array", "textures"), 'w') as sys.stdout:
+ print "((function texture1DArray"
+ generate_sigs("", "tex", "1DArray")
+ print ")\n (function texture1DArrayLod"
+ generate_sigs("", "txl", "1DArray")
+ print ")\n (function texture2DArray"
+ generate_sigs("", "tex", "2DArray")
+ print ")\n (function texture2DArrayLod"
+ generate_sigs("", "txl", "2DArray")
+ print ")\n (function shadow1DArray"
+ generate_sigs("", "tex", "1DArrayShadow")
+ print ")\n (function shadow1DArrayLod"
+ generate_sigs("", "txl", "1DArrayShadow")
+ print ")\n (function shadow2DArray"
+ generate_sigs("", "tex", "2DArrayShadow")
+ print "))"
+
+with open(path.join(builtins_dir, "EXT_texture_array_fs", "textures"), 'w') as sys.stdout:
+ print "((function texture1DArray"
+ generate_sigs("", "txb", "1DArray") # MOVE TO _fs
+ print ")\n (function texture2DArray"
+ generate_sigs("", "txb", "2DArray") # MOVE TO _fs
+ print ")\n (function shadow1DArray"
+ generate_sigs("", "txb", "1DArrayShadow")
+ print "))"
+
+# Deprecated (110/120 style) functions with silly names:
+with open(path.join(builtins_dir, "110", "textures"), 'w') as sys.stdout:
+ print "((function texture1D"
+ generate_sigs("", "tex", "1D")
+ print ")\n (function texture1DLod"
+ generate_sigs("", "txl", "1D")
+ print ")\n (function texture1DProj"
+ generate_sigs("", "tex", "1D", True)
+ generate_sigs("", "tex", "1D", True, 2)
+ print ")\n (function texture1DProjLod"
+ generate_sigs("", "txl", "1D", True)
+ generate_sigs("", "txl", "1D", True, 2)
+ print ")\n (function texture2D"
+ generate_sigs("", "tex", "2D")
+ print ")\n(function texture2DLod"
+ generate_sigs("", "txl", "2D")
+ print ")\n (function texture2DProj"
+ generate_sigs("", "tex", "2D", True)
+ generate_sigs("", "tex", "2D", True, 1)
+ print ")\n (function texture2DProjLod"
+ generate_sigs("", "txl", "2D", True)
+ generate_sigs("", "txl", "2D", True, 1)
+ print ")\n (function texture3D"
+ generate_sigs("", "tex", "3D")
+ print ")\n (function texture3DLod"
+ generate_sigs("", "txl", "3D")
+ print ")\n (function texture3DProj"
+ generate_sigs("", "tex", "3D", True)
+ print ")\n (function texture3DProjLod"
+ generate_sigs("", "txl", "3D", True)
+ print ")\n (function textureCube"
+ generate_sigs("", "tex", "Cube")
+ print ")\n (function textureCubeLod"
+ generate_sigs("", "txl", "Cube")
+ print ")\n (function shadow1D"
+ generate_sigs("", "tex", "1DShadow", False, 1)
+ print ")\n (function shadow1DLod"
+ generate_sigs("", "txl", "1DShadow", False, 1)
+ print ")\n (function shadow1DProj"
+ generate_sigs("", "tex", "1DShadow", True, 1)
+ print ")\n (function shadow1DProjLod"
+ generate_sigs("", "txl", "1DShadow", True, 1)
+ print ")\n (function shadow2D"
+ generate_sigs("", "tex", "2DShadow")
+ print ")\n (function shadow2DLod"
+ generate_sigs("", "txl", "2DShadow")
+ print ")\n (function shadow2DProj"
+ generate_sigs("", "tex", "2DShadow", True)
+ print ")\n (function shadow2DProjLod"
+ generate_sigs("", "txl", "2DShadow", True)
+ print "))"
+
+with open(path.join(builtins_dir, "110_fs", "textures"), 'w') as sys.stdout:
+ print "((function texture1D"
+ generate_sigs("", "txb", "1D")
+ print ")\n (function texture1DProj"
+ generate_sigs("", "txb", "1D", True)
+ generate_sigs("", "txb", "1D", True, 2)
+ print ")\n (function texture2D"
+ generate_sigs("", "txb", "2D")
+ print ")\n (function texture2DProj"
+ generate_sigs("", "txb", "2D", True)
+ generate_sigs("", "txb", "2D", True, 1)
+ print ")\n (function texture3D"
+ generate_sigs("", "txb", "3D")
+ print ")\n (function texture3DProj"
+ generate_sigs("", "txb", "3D", True)
+ print ")\n (function textureCube"
+ generate_sigs("", "txb", "Cube")
+ print ")\n (function shadow1D"
+ generate_sigs("", "txb", "1DShadow", False, 1)
+ print ")\n (function shadow1DProj"
+ generate_sigs("", "txb", "1DShadow", True, 1)
+ print ")\n (function shadow2D"
+ generate_sigs("", "txb", "2DShadow")
+ print ")\n (function shadow2DProj"
+ generate_sigs("", "txb", "2DShadow", True)
+ print "))"
--- /dev/null
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.61)
+AC_INIT(glsl, XXXXX, idr@freedesktop.org, glsl)
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_CONFIG_HEADER([config.h])
+AC_CONFIG_FILES([glcpp/Makefile])
+
+AM_INIT_AUTOMAKE
+LT_INIT
+
+AM_MAINTAINER_MODE
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_MAKE_SET
+AC_PROG_YACC
+AC_PROG_LEX
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+# Checks for libraries.
+
+# Checks for header files.
+
+# Checks for typedefs, structures, and compiler characteristics.
+
+# Checks for library functions.
+AC_HEADER_STDC
+
+AH_TOP([#ifndef GLSL_CONFIG_H
+#define GLSL_CONFIG_H])
+AH_BOTTOM([#endif /* GLSL_CONFIG_H */])
+
+PKG_CHECK_MODULES([talloc], [talloc >= 2.0])
+
+AC_ARG_ENABLE([debug],
+ [AS_HELP_STRING([--enable-debug],
+ [use debug compiler flags and macros @<:@default=disabled@:>@])],
+ [enable_debug="$enableval"],
+ [enable_debug=no]
+)
+if test "x$enable_debug" = xyes; then
+ DEFINES="$DEFINES -DDEBUG"
+ if test "x$GCC" = xyes; then
+ # Remove any -g or -O flags from the command line
+ CFLAGS=[`echo $CFLAGS | sed 's/-g[^ \t]*[ \t]*//g;s/-O[^ \t]*[ \t]*//g'`]
+ CFLAGS="$CFLAGS -O0 -ggdb3 -fstack-protector -D_FORTIFY_SOURCE=2"
+ fi
+ if test "x$GXX" = xyes; then
+ # Remove any -g flags from the command line
+ CXXFLAGS=[`echo $CXXFLAGS | sed 's/-g[^ \t]*[ \t]*//g;s/-O[^ \t]*[ \t]*//g'`]
+ CXXFLAGS="$CXXFLAGS -O0 -ggdb3 -fstack-protector -D_FORTIFY_SOURCE=2"
+ fi
+fi
+
+if test "x$GXX" = xyes ; then
+ WARN="-Wall -Wextra -Wunsafe-loop-optimizations -Wstack-protector"
+else
+ WARN=""
+fi
+
+CFLAGS="$CFLAGS $WARN"
+CXXFLAGS="$CXXFLAGS $WARN"
+YFLAGS="-d -v"
+
+AC_OUTPUT([Makefile])
--- /dev/null
+glcpp
+glcpp-lex.c
+glcpp-parse.c
+glcpp-parse.h
+glcpp-parse.output
+*.o
+*.lo
+*.la
+.libs
+*~
+tests/*.out
--- /dev/null
+# Copyright © 2010 Intel Corporation
+# 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
+# on 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
+# AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR 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.
+
+noinst_LTLIBRARIES = libglcpp.la
+libglcpp_la_SOURCES = \
+ glcpp-lex.l \
+ glcpp-parse.y \
+ glcpp.h \
+ hash_table.c \
+ pp.c \
+ xtalloc.c
+
+BUILT_SOURCES = glcpp-parse.h glcpp-parse.c glcpp-lex.c
+CLEANFILES = $(BUILT_SOURCES)
+
+glcpp-parse.h: glcpp-parse.c
+
+bin_PROGRAMS = glcpp
+glcpp_LDADD = libglcpp.la
+glcpp_LDFLAGS = @LDFLAGS@ $(talloc_LIBS)
+glcpp_SOURCES = glcpp.c
+
+.l.c:
+ $(LEXCOMPILE) --outfile="$@" $<
+
+test: glcpp
+ @(cd tests; ./glcpp-test)
--- /dev/null
+glcpp -- GLSL "C" preprocessor
+
+This is a simple preprocessor designed to provide the preprocessing
+needs of the GLSL language. The requirements for this preprocessor are
+specified in the GLSL 1.30 specification availble from:
+
+http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.30.08.pdf
+
+This specification is not precise on some semantics, (for example,
+#define and #if), defining these merely "as is standard for C++
+preprocessors". To fill in these details, I've been using the C99
+standard (for which I had a convenient copy) as available from:
+
+http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
+
+Known limitations
+-----------------
+Macro invocations cannot include embedded newlines.
+
+The __LINE__, __FILE__, and __VERSION__ macros are not yet supported.
+
+The argument of the 'defined' operator cannot yet include enclosing
+parentheses.
+
+The #error, #pragma, #extension, #version, and #line macros are not
+yet supported.
+
+A file that ends with a function-like macro name as the last
+non-whitespace token will result in a parse error, (where it should be
+passed through as is).
\ No newline at end of file
--- /dev/null
+%{
+/*
+ * 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 <stdio.h>
+#include <string.h>
+
+#include "glcpp.h"
+#include "glcpp-parse.h"
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->source = 0; \
+ yylloc->first_column = yycolumn + 1; \
+ yylloc->first_line = yylineno; \
+ yycolumn += yyleng; \
+ } while(0);
+%}
+
+%option bison-bridge bison-locations reentrant noyywrap
+%option extra-type="glcpp_parser_t *"
+%option prefix="glcpp_"
+%option stack
+
+%x DONE COMMENT
+
+SPACE [[:space:]]
+NONSPACE [^[:space:]]
+NEWLINE [\n]
+HSPACE [ \t]
+HASH ^{HSPACE}*#{HSPACE}*
+IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
+PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
+OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
+
+DECIMAL_INTEGER [1-9][0-9]*[uU]?
+OCTAL_INTEGER 0[0-7]*[uU]?
+HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
+
+%%
+
+ /* Single-line comments */
+"//"[^\n]*\n {
+ yylineno++;
+ yycolumn = 0;
+ return NEWLINE;
+}
+
+ /* Multi-line comments */
+"/*" { yy_push_state(COMMENT, yyscanner); }
+<COMMENT>[^*\n]*
+<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; }
+<COMMENT>"*"+[^*/\n]*
+<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; }
+<COMMENT>"*"+"/" {
+ yy_pop_state(yyscanner);
+ if (yyextra->space_tokens)
+ return SPACE;
+}
+
+ /* glcpp doesn't handle #extension, #version, or #pragma directives.
+ * Simply pass them through to the main compiler's lexer/parser. */
+{HASH}(extension|version|pragma)[^\n]+ {
+ yylval->str = xtalloc_strdup (yyextra, yytext);
+ yylineno++;
+ yycolumn = 0;
+ return OTHER;
+}
+
+{HASH}ifdef/.*\n {
+ yyextra->space_tokens = 0;
+ return HASH_IFDEF;
+}
+
+{HASH}ifndef/.*\n {
+ yyextra->space_tokens = 0;
+ return HASH_IFNDEF;
+}
+
+{HASH}if{HSPACE}/.*\n {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IF;
+}
+
+{HASH}elif/.*\n {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_ELIF;
+}
+
+{HASH}else/.*\n {
+ yyextra->space_tokens = 0;
+ return HASH_ELSE;
+}
+
+{HASH}endif/.*\n {
+ yyextra->space_tokens = 0;
+ return HASH_ENDIF;
+}
+
+ /* When skipping (due to an #if 0 or similar) consume anything
+ * up to a newline. We do this less priroty than any
+ * #if-related directive (#if, #elif, #else, #endif), but with
+ * more priority than any other directive or token to avoid
+ * any side-effects from skipped content.
+ *
+ * We use the lexing_if flag to avoid skipping any part of an
+ * if conditional expression. */
+[^\n]+/\n {
+ /* Since this rule always matches, YY_USER_ACTION gets called for it,
+ * wrongly incrementing yycolumn. We undo that effect here. */
+ yycolumn -= yyleng;
+ if (yyextra->lexing_if ||
+ yyextra->skip_stack == NULL ||
+ yyextra->skip_stack->type == SKIP_NO_SKIP)
+ {
+ REJECT;
+ }
+}
+
+{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
+ yyextra->space_tokens = 0;
+ return HASH_DEFINE_FUNC;
+}
+
+{HASH}define {
+ yyextra->space_tokens = 0;
+ return HASH_DEFINE_OBJ;
+}
+
+{HASH}undef {
+ yyextra->space_tokens = 0;
+ return HASH_UNDEF;
+}
+
+{HASH} {
+ yyextra->space_tokens = 0;
+ return HASH;
+}
+
+{DECIMAL_INTEGER} {
+ yylval->str = xtalloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+{OCTAL_INTEGER} {
+ yylval->str = xtalloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+{HEXADECIMAL_INTEGER} {
+ yylval->str = xtalloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+"<<" {
+ return LEFT_SHIFT;
+}
+
+">>" {
+ return RIGHT_SHIFT;
+}
+
+"<=" {
+ return LESS_OR_EQUAL;
+}
+
+">=" {
+ return GREATER_OR_EQUAL;
+}
+
+"==" {
+ return EQUAL;
+}
+
+"!=" {
+ return NOT_EQUAL;
+}
+
+"&&" {
+ return AND;
+}
+
+"||" {
+ return OR;
+}
+
+"##" {
+ return PASTE;
+}
+
+"defined" {
+ return DEFINED;
+}
+
+{IDENTIFIER} {
+ yylval->str = xtalloc_strdup (yyextra, yytext);
+ return IDENTIFIER;
+}
+
+{PUNCTUATION} {
+ return yytext[0];
+}
+
+{OTHER}+ {
+ yylval->str = xtalloc_strdup (yyextra, yytext);
+ return OTHER;
+}
+
+{HSPACE}+ {
+ if (yyextra->space_tokens) {
+ return SPACE;
+ }
+}
+
+\n {
+ yyextra->lexing_if = 0;
+ yylineno++;
+ yycolumn = 0;
+ return NEWLINE;
+}
+
+ /* Handle missing newline at EOF. */
+<INITIAL><<EOF>> {
+ BEGIN DONE; /* Don't keep matching this rule forever. */
+ yyextra->lexing_if = 0;
+ return NEWLINE;
+}
+
+%%
+
+void
+glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
+{
+ yy_scan_string(shader, parser->scanner);
+}
--- /dev/null
+%{
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <inttypes.h>
+
+#include "glcpp.h"
+
+#define glcpp_print(stream, str) stream = talloc_strdup_append(stream, str)
+#define glcpp_printf(stream, fmt, args...) \
+ stream = talloc_asprintf_append(stream, fmt, args)
+
+static void
+yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
+
+static void
+_define_object_macro (glcpp_parser_t *parser,
+ YYLTYPE *loc,
+ const char *macro,
+ token_list_t *replacements);
+
+static void
+_define_function_macro (glcpp_parser_t *parser,
+ YYLTYPE *loc,
+ const char *macro,
+ string_list_t *parameters,
+ token_list_t *replacements);
+
+static string_list_t *
+_string_list_create (void *ctx);
+
+static void
+_string_list_append_item (string_list_t *list, const char *str);
+
+static int
+_string_list_contains (string_list_t *list, const char *member, int *index);
+
+static int
+_string_list_length (string_list_t *list);
+
+static argument_list_t *
+_argument_list_create (void *ctx);
+
+static void
+_argument_list_append (argument_list_t *list, token_list_t *argument);
+
+static int
+_argument_list_length (argument_list_t *list);
+
+static token_list_t *
+_argument_list_member_at (argument_list_t *list, int index);
+
+/* Note: This function talloc_steal()s the str pointer. */
+static token_t *
+_token_create_str (void *ctx, int type, char *str);
+
+static token_t *
+_token_create_ival (void *ctx, int type, int ival);
+
+static token_list_t *
+_token_list_create (void *ctx);
+
+/* Note: This function adds a talloc_reference() to token.
+ *
+ * You may want to talloc_unlink any current reference if you no
+ * longer need it. */
+static void
+_token_list_append (token_list_t *list, token_t *token);
+
+static void
+_token_list_append_list (token_list_t *list, token_list_t *tail);
+
+static active_list_t *
+_active_list_push (active_list_t *list,
+ const char *identifier,
+ token_node_t *marker);
+
+static active_list_t *
+_active_list_pop (active_list_t *list);
+
+int
+_active_list_contains (active_list_t *list, const char *identifier);
+
+static void
+_glcpp_parser_expand_token_list (glcpp_parser_t *parser,
+ token_list_t *list);
+
+static void
+_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
+ token_list_t *list);
+
+static void
+_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
+ int condition);
+
+static void
+_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
+ const char *type, int condition);
+
+static void
+_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc);
+
+#define yylex glcpp_parser_lex
+
+static int
+glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser);
+
+static void
+glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list);
+
+%}
+
+%pure-parser
+%error-verbose
+%locations
+
+%parse-param {glcpp_parser_t *parser}
+%lex-param {glcpp_parser_t *parser}
+
+%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE_FUNC HASH_DEFINE_OBJ HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF HASH_UNDEF IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING NEWLINE OTHER PLACEHOLDER SPACE
+%token PASTE
+%type <ival> expression INTEGER operator SPACE
+%type <str> IDENTIFIER INTEGER_STRING OTHER
+%type <string_list> identifier_list
+%type <token> preprocessing_token conditional_token
+%type <token_list> pp_tokens replacement_list text_line conditional_tokens
+%left OR
+%left AND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOT_EQUAL
+%left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL
+%left LEFT_SHIFT RIGHT_SHIFT
+%left '+' '-'
+%left '*' '/' '%'
+%right UNARY
+
+%%
+
+input:
+ /* empty */
+| input line
+;
+
+line:
+ control_line {
+ glcpp_print(parser->output, "\n");
+ }
+| text_line {
+ _glcpp_parser_print_expanded_token_list (parser, $1);
+ glcpp_print(parser->output, "\n");
+ talloc_free ($1);
+ }
+| expanded_line
+| HASH non_directive
+;
+
+expanded_line:
+ IF_EXPANDED expression NEWLINE {
+ _glcpp_parser_skip_stack_push_if (parser, & @1, $2);
+ }
+| ELIF_EXPANDED expression NEWLINE {
+ _glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2);
+ }
+;
+
+control_line:
+ HASH_DEFINE_OBJ IDENTIFIER replacement_list NEWLINE {
+ _define_object_macro (parser, & @2, $2, $3);
+ }
+| HASH_DEFINE_FUNC IDENTIFIER '(' ')' replacement_list NEWLINE {
+ _define_function_macro (parser, & @2, $2, NULL, $5);
+ }
+| HASH_DEFINE_FUNC IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE {
+ _define_function_macro (parser, & @2, $2, $4, $6);
+ }
+| HASH_UNDEF IDENTIFIER NEWLINE {
+ macro_t *macro = hash_table_find (parser->defines, $2);
+ if (macro) {
+ /* XXX: Need hash table to support a real way
+ * to remove an element rather than prefixing
+ * a new node with data of NULL like this. */
+ hash_table_insert (parser->defines, NULL, $2);
+ talloc_free (macro);
+ }
+ talloc_free ($2);
+ }
+| HASH_IF conditional_tokens NEWLINE {
+ token_list_t *expanded;
+ token_t *token;
+
+ expanded = _token_list_create (parser);
+ token = _token_create_ival (parser, IF_EXPANDED, IF_EXPANDED);
+ _token_list_append (expanded, token);
+ talloc_unlink (parser, token);
+ _glcpp_parser_expand_token_list (parser, $2);
+ _token_list_append_list (expanded, $2);
+ glcpp_parser_lex_from (parser, expanded);
+ }
+| HASH_IFDEF IDENTIFIER junk NEWLINE {
+ macro_t *macro = hash_table_find (parser->defines, $2);
+ talloc_free ($2);
+ _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
+ }
+| HASH_IFNDEF IDENTIFIER junk NEWLINE {
+ macro_t *macro = hash_table_find (parser->defines, $2);
+ talloc_free ($2);
+ _glcpp_parser_skip_stack_push_if (parser, & @1, macro == NULL);
+ }
+| HASH_ELIF conditional_tokens NEWLINE {
+ token_list_t *expanded;
+ token_t *token;
+
+ expanded = _token_list_create (parser);
+ token = _token_create_ival (parser, ELIF_EXPANDED, ELIF_EXPANDED);
+ _token_list_append (expanded, token);
+ talloc_unlink (parser, token);
+ _glcpp_parser_expand_token_list (parser, $2);
+ _token_list_append_list (expanded, $2);
+ glcpp_parser_lex_from (parser, expanded);
+ }
+| HASH_ELIF NEWLINE {
+ /* #elif without an expression results in a warning if the
+ * condition doesn't matter (we just handled #if 1 or such)
+ * but an error otherwise. */
+ if (parser->skip_stack != NULL && parser->skip_stack->type == SKIP_NO_SKIP) {
+ parser->skip_stack->type = SKIP_TO_ENDIF;
+ glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
+ } else {
+ glcpp_error(& @1, parser, "#elif needs an expression");
+ }
+ }
+| HASH_ELSE NEWLINE {
+ _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
+ }
+| HASH_ENDIF NEWLINE {
+ _glcpp_parser_skip_stack_pop (parser, & @1);
+ }
+| HASH NEWLINE
+;
+
+expression:
+ INTEGER_STRING {
+ if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) {
+ $$ = strtoll ($1 + 2, NULL, 16);
+ } else if ($1[0] == '0') {
+ $$ = strtoll ($1, NULL, 8);
+ } else {
+ $$ = strtoll ($1, NULL, 10);
+ }
+ }
+| INTEGER {
+ $$ = $1;
+ }
+| expression OR expression {
+ $$ = $1 || $3;
+ }
+| expression AND expression {
+ $$ = $1 && $3;
+ }
+| expression '|' expression {
+ $$ = $1 | $3;
+ }
+| expression '^' expression {
+ $$ = $1 ^ $3;
+ }
+| expression '&' expression {
+ $$ = $1 & $3;
+ }
+| expression NOT_EQUAL expression {
+ $$ = $1 != $3;
+ }
+| expression EQUAL expression {
+ $$ = $1 == $3;
+ }
+| expression GREATER_OR_EQUAL expression {
+ $$ = $1 >= $3;
+ }
+| expression LESS_OR_EQUAL expression {
+ $$ = $1 <= $3;
+ }
+| expression '>' expression {
+ $$ = $1 > $3;
+ }
+| expression '<' expression {
+ $$ = $1 < $3;
+ }
+| expression RIGHT_SHIFT expression {
+ $$ = $1 >> $3;
+ }
+| expression LEFT_SHIFT expression {
+ $$ = $1 << $3;
+ }
+| expression '-' expression {
+ $$ = $1 - $3;
+ }
+| expression '+' expression {
+ $$ = $1 + $3;
+ }
+| expression '%' expression {
+ $$ = $1 % $3;
+ }
+| expression '/' expression {
+ $$ = $1 / $3;
+ }
+| expression '*' expression {
+ $$ = $1 * $3;
+ }
+| '!' expression %prec UNARY {
+ $$ = ! $2;
+ }
+| '~' expression %prec UNARY {
+ $$ = ~ $2;
+ }
+| '-' expression %prec UNARY {
+ $$ = - $2;
+ }
+| '+' expression %prec UNARY {
+ $$ = + $2;
+ }
+| '(' expression ')' {
+ $$ = $2;
+ }
+;
+
+identifier_list:
+ IDENTIFIER {
+ $$ = _string_list_create (parser);
+ _string_list_append_item ($$, $1);
+ talloc_steal ($$, $1);
+ }
+| identifier_list ',' IDENTIFIER {
+ $$ = $1;
+ _string_list_append_item ($$, $3);
+ talloc_steal ($$, $3);
+ }
+;
+
+text_line:
+ NEWLINE { $$ = NULL; }
+| pp_tokens NEWLINE
+;
+
+non_directive:
+ pp_tokens NEWLINE {
+ yyerror (& @1, parser, "Invalid tokens after #");
+ }
+;
+
+replacement_list:
+ /* empty */ { $$ = NULL; }
+| pp_tokens
+;
+
+junk:
+ /* empty */
+| pp_tokens {
+ glcpp_warning(&@1, parser, "extra tokens at end of directive");
+ }
+;
+
+conditional_token:
+ /* Handle "defined" operator */
+ DEFINED IDENTIFIER {
+ int v = hash_table_find (parser->defines, $2) ? 1 : 0;
+ $$ = _token_create_ival (parser, INTEGER, v);
+ }
+| DEFINED '(' IDENTIFIER ')' {
+ int v = hash_table_find (parser->defines, $3) ? 1 : 0;
+ $$ = _token_create_ival (parser, INTEGER, v);
+ }
+| preprocessing_token
+;
+
+conditional_tokens:
+ /* Exactly the same as pp_tokens, but using conditional_token */
+ conditional_token {
+ parser->space_tokens = 1;
+ $$ = _token_list_create (parser);
+ _token_list_append ($$, $1);
+ talloc_unlink (parser, $1);
+ }
+| conditional_tokens conditional_token {
+ $$ = $1;
+ _token_list_append ($$, $2);
+ talloc_unlink (parser, $2);
+ }
+;
+
+pp_tokens:
+ preprocessing_token {
+ parser->space_tokens = 1;
+ $$ = _token_list_create (parser);
+ _token_list_append ($$, $1);
+ talloc_unlink (parser, $1);
+ }
+| pp_tokens preprocessing_token {
+ $$ = $1;
+ _token_list_append ($$, $2);
+ talloc_unlink (parser, $2);
+ }
+;
+
+preprocessing_token:
+ IDENTIFIER {
+ $$ = _token_create_str (parser, IDENTIFIER, $1);
+ $$->location = yylloc;
+ }
+| INTEGER_STRING {
+ $$ = _token_create_str (parser, INTEGER_STRING, $1);
+ $$->location = yylloc;
+ }
+| operator {
+ $$ = _token_create_ival (parser, $1, $1);
+ $$->location = yylloc;
+ }
+| OTHER {
+ $$ = _token_create_str (parser, OTHER, $1);
+ $$->location = yylloc;
+ }
+| SPACE {
+ $$ = _token_create_ival (parser, SPACE, SPACE);
+ $$->location = yylloc;
+ }
+;
+
+operator:
+ '[' { $$ = '['; }
+| ']' { $$ = ']'; }
+| '(' { $$ = '('; }
+| ')' { $$ = ')'; }
+| '{' { $$ = '{'; }
+| '}' { $$ = '}'; }
+| '.' { $$ = '.'; }
+| '&' { $$ = '&'; }
+| '*' { $$ = '*'; }
+| '+' { $$ = '+'; }
+| '-' { $$ = '-'; }
+| '~' { $$ = '~'; }
+| '!' { $$ = '!'; }
+| '/' { $$ = '/'; }
+| '%' { $$ = '%'; }
+| LEFT_SHIFT { $$ = LEFT_SHIFT; }
+| RIGHT_SHIFT { $$ = RIGHT_SHIFT; }
+| '<' { $$ = '<'; }
+| '>' { $$ = '>'; }
+| LESS_OR_EQUAL { $$ = LESS_OR_EQUAL; }
+| GREATER_OR_EQUAL { $$ = GREATER_OR_EQUAL; }
+| EQUAL { $$ = EQUAL; }
+| NOT_EQUAL { $$ = NOT_EQUAL; }
+| '^' { $$ = '^'; }
+| '|' { $$ = '|'; }
+| AND { $$ = AND; }
+| OR { $$ = OR; }
+| ';' { $$ = ';'; }
+| ',' { $$ = ','; }
+| '=' { $$ = '='; }
+| PASTE { $$ = PASTE; }
+| DEFINED { $$ = DEFINED; }
+;
+
+%%
+
+string_list_t *
+_string_list_create (void *ctx)
+{
+ string_list_t *list;
+
+ list = xtalloc (ctx, string_list_t);
+ list->head = NULL;
+ list->tail = NULL;
+
+ return list;
+}
+
+void
+_string_list_append_item (string_list_t *list, const char *str)
+{
+ string_node_t *node;
+
+ node = xtalloc (list, string_node_t);
+ node->str = xtalloc_strdup (node, str);
+
+ node->next = NULL;
+
+ if (list->head == NULL) {
+ list->head = node;
+ } else {
+ list->tail->next = node;
+ }
+
+ list->tail = node;
+}
+
+int
+_string_list_contains (string_list_t *list, const char *member, int *index)
+{
+ string_node_t *node;
+ int i;
+
+ if (list == NULL)
+ return 0;
+
+ for (i = 0, node = list->head; node; i++, node = node->next) {
+ if (strcmp (node->str, member) == 0) {
+ if (index)
+ *index = i;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int
+_string_list_length (string_list_t *list)
+{
+ int length = 0;
+ string_node_t *node;
+
+ if (list == NULL)
+ return 0;
+
+ for (node = list->head; node; node = node->next)
+ length++;
+
+ return length;
+}
+
+argument_list_t *
+_argument_list_create (void *ctx)
+{
+ argument_list_t *list;
+
+ list = xtalloc (ctx, argument_list_t);
+ list->head = NULL;
+ list->tail = NULL;
+
+ return list;
+}
+
+void
+_argument_list_append (argument_list_t *list, token_list_t *argument)
+{
+ argument_node_t *node;
+
+ node = xtalloc (list, argument_node_t);
+ node->argument = argument;
+
+ node->next = NULL;
+
+ if (list->head == NULL) {
+ list->head = node;
+ } else {
+ list->tail->next = node;
+ }
+
+ list->tail = node;
+}
+
+int
+_argument_list_length (argument_list_t *list)
+{
+ int length = 0;
+ argument_node_t *node;
+
+ if (list == NULL)
+ return 0;
+
+ for (node = list->head; node; node = node->next)
+ length++;
+
+ return length;
+}
+
+token_list_t *
+_argument_list_member_at (argument_list_t *list, int index)
+{
+ argument_node_t *node;
+ int i;
+
+ if (list == NULL)
+ return NULL;
+
+ node = list->head;
+ for (i = 0; i < index; i++) {
+ node = node->next;
+ if (node == NULL)
+ break;
+ }
+
+ if (node)
+ return node->argument;
+
+ return NULL;
+}
+
+/* Note: This function talloc_steal()s the str pointer. */
+token_t *
+_token_create_str (void *ctx, int type, char *str)
+{
+ token_t *token;
+
+ token = xtalloc (ctx, token_t);
+ token->type = type;
+ token->value.str = talloc_steal (token, str);
+
+ return token;
+}
+
+token_t *
+_token_create_ival (void *ctx, int type, int ival)
+{
+ token_t *token;
+
+ token = xtalloc (ctx, token_t);
+ token->type = type;
+ token->value.ival = ival;
+
+ return token;
+}
+
+token_list_t *
+_token_list_create (void *ctx)
+{
+ token_list_t *list;
+
+ list = xtalloc (ctx, token_list_t);
+ list->head = NULL;
+ list->tail = NULL;
+ list->non_space_tail = NULL;
+
+ return list;
+}
+
+void
+_token_list_append (token_list_t *list, token_t *token)
+{
+ token_node_t *node;
+
+ node = xtalloc (list, token_node_t);
+ node->token = xtalloc_reference (list, token);
+
+ node->next = NULL;
+
+ if (list->head == NULL) {
+ list->head = node;
+ } else {
+ list->tail->next = node;
+ }
+
+ list->tail = node;
+ if (token->type != SPACE)
+ list->non_space_tail = node;
+}
+
+void
+_token_list_append_list (token_list_t *list, token_list_t *tail)
+{
+ if (tail == NULL || tail->head == NULL)
+ return;
+
+ if (list->head == NULL) {
+ list->head = tail->head;
+ } else {
+ list->tail->next = tail->head;
+ }
+
+ list->tail = tail->tail;
+ list->non_space_tail = tail->non_space_tail;
+}
+
+token_list_t *
+_token_list_copy (void *ctx, token_list_t *other)
+{
+ token_list_t *copy;
+ token_node_t *node;
+
+ if (other == NULL)
+ return NULL;
+
+ copy = _token_list_create (ctx);
+ for (node = other->head; node; node = node->next)
+ _token_list_append (copy, node->token);
+
+ return copy;
+}
+
+void
+_token_list_trim_trailing_space (token_list_t *list)
+{
+ token_node_t *tail, *next;
+
+ if (list->non_space_tail) {
+ tail = list->non_space_tail->next;
+ list->non_space_tail->next = NULL;
+ list->tail = list->non_space_tail;
+
+ while (tail) {
+ next = tail->next;
+ talloc_free (tail);
+ tail = next;
+ }
+ }
+}
+
+static void
+_token_print (char **out, token_t *token)
+{
+ if (token->type < 256) {
+ glcpp_printf (*out, "%c", token->type);
+ return;
+ }
+
+ switch (token->type) {
+ case INTEGER:
+ glcpp_printf (*out, "%" PRIxMAX, token->value.ival);
+ break;
+ case IDENTIFIER:
+ case INTEGER_STRING:
+ case OTHER:
+ glcpp_print (*out, token->value.str);
+ break;
+ case SPACE:
+ glcpp_print (*out, " ");
+ break;
+ case LEFT_SHIFT:
+ glcpp_print (*out, "<<");
+ break;
+ case RIGHT_SHIFT:
+ glcpp_print (*out, ">>");
+ break;
+ case LESS_OR_EQUAL:
+ glcpp_print (*out, "<=");
+ break;
+ case GREATER_OR_EQUAL:
+ glcpp_print (*out, ">=");
+ break;
+ case EQUAL:
+ glcpp_print (*out, "==");
+ break;
+ case NOT_EQUAL:
+ glcpp_print (*out, "!=");
+ break;
+ case AND:
+ glcpp_print (*out, "&&");
+ break;
+ case OR:
+ glcpp_print (*out, "||");
+ break;
+ case PASTE:
+ glcpp_print (*out, "##");
+ break;
+ case COMMA_FINAL:
+ glcpp_print (*out, ",");
+ break;
+ case PLACEHOLDER:
+ /* Nothing to print. */
+ break;
+ default:
+ assert(!"Error: Don't know how to print token.");
+ break;
+ }
+}
+
+/* Return a new token (talloc()ed off of 'token') formed by pasting
+ * 'token' and 'other'. Note that this function may return 'token' or
+ * 'other' directly rather than allocating anything new.
+ *
+ * Caution: Only very cursory error-checking is performed to see if
+ * the final result is a valid single token. */
+static token_t *
+_token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
+{
+ token_t *combined = NULL;
+
+ /* Pasting a placeholder onto anything makes no change. */
+ if (other->type == PLACEHOLDER)
+ return token;
+
+ /* When 'token' is a placeholder, just return 'other'. */
+ if (token->type == PLACEHOLDER)
+ return other;
+
+ /* A very few single-character punctuators can be combined
+ * with another to form a multi-character punctuator. */
+ switch (token->type) {
+ case '<':
+ if (other->type == '<')
+ combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT);
+ else if (other->type == '=')
+ combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL);
+ break;
+ case '>':
+ if (other->type == '>')
+ combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT);
+ else if (other->type == '=')
+ combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
+ break;
+ case '=':
+ if (other->type == '=')
+ combined = _token_create_ival (token, EQUAL, EQUAL);
+ break;
+ case '!':
+ if (other->type == '=')
+ combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL);
+ break;
+ case '&':
+ if (other->type == '&')
+ combined = _token_create_ival (token, AND, AND);
+ break;
+ case '|':
+ if (other->type == '|')
+ combined = _token_create_ival (token, OR, OR);
+ break;
+ }
+
+ if (combined != NULL) {
+ /* Inherit the location from the first token */
+ combined->location = token->location;
+ return combined;
+ }
+
+ /* Two string-valued tokens can usually just be mashed
+ * together.
+ *
+ * XXX: This isn't actually legitimate. Several things here
+ * should result in a diagnostic since the result cannot be a
+ * valid, single pre-processing token. For example, pasting
+ * "123" and "abc" is not legal, but we don't catch that
+ * here. */
+ if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING) &&
+ (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING))
+ {
+ char *str;
+
+ str = xtalloc_asprintf (token, "%s%s",
+ token->value.str, other->value.str);
+ combined = _token_create_str (token, token->type, str);
+ combined->location = token->location;
+ return combined;
+ }
+
+ glcpp_error (&token->location, parser, "");
+ glcpp_print (parser->info_log, "Pasting \"");
+ _token_print (&parser->info_log, token);
+ glcpp_print (parser->info_log, "\" and \"");
+ _token_print (&parser->info_log, other);
+ glcpp_print (parser->info_log, "\" does not give a valid preprocessing token.\n");
+
+ return token;
+}
+
+static void
+_token_list_print (glcpp_parser_t *parser, token_list_t *list)
+{
+ token_node_t *node;
+
+ if (list == NULL)
+ return;
+
+ for (node = list->head; node; node = node->next)
+ _token_print (&parser->output, node->token);
+}
+
+void
+yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error)
+{
+ glcpp_error(locp, parser, "%s", error);
+}
+
+glcpp_parser_t *
+glcpp_parser_create (void)
+{
+ glcpp_parser_t *parser;
+
+ parser = xtalloc (NULL, glcpp_parser_t);
+
+ glcpp_lex_init_extra (parser, &parser->scanner);
+ parser->defines = hash_table_ctor (32, hash_table_string_hash,
+ hash_table_string_compare);
+ parser->active = NULL;
+ parser->lexing_if = 0;
+ parser->space_tokens = 1;
+ parser->newline_as_space = 0;
+ parser->in_control_line = 0;
+ parser->paren_count = 0;
+
+ parser->skip_stack = NULL;
+
+ parser->lex_from_list = NULL;
+ parser->lex_from_node = NULL;
+
+ parser->output = talloc_strdup(parser, "");
+ parser->info_log = talloc_strdup(parser, "");
+ parser->error = 0;
+
+ return parser;
+}
+
+int
+glcpp_parser_parse (glcpp_parser_t *parser)
+{
+ return yyparse (parser);
+}
+
+void
+glcpp_parser_destroy (glcpp_parser_t *parser)
+{
+ if (parser->skip_stack)
+ glcpp_error (&parser->skip_stack->loc, parser, "Unterminated #if\n");
+ glcpp_lex_destroy (parser->scanner);
+ hash_table_dtor (parser->defines);
+ talloc_free (parser);
+}
+
+typedef enum function_status
+{
+ FUNCTION_STATUS_SUCCESS,
+ FUNCTION_NOT_A_FUNCTION,
+ FUNCTION_UNBALANCED_PARENTHESES
+} function_status_t;
+
+/* Find a set of function-like macro arguments by looking for a
+ * balanced set of parentheses.
+ *
+ * When called, 'node' should be the opening-parenthesis token, (or
+ * perhaps preceeding SPACE tokens). Upon successful return *last will
+ * be the last consumed node, (corresponding to the closing right
+ * parenthesis).
+ *
+ * Return values:
+ *
+ * FUNCTION_STATUS_SUCCESS:
+ *
+ * Successfully parsed a set of function arguments.
+ *
+ * FUNCTION_NOT_A_FUNCTION:
+ *
+ * Macro name not followed by a '('. This is not an error, but
+ * simply that the macro name should be treated as a non-macro.
+ *
+ * FUNCTION_UNBALANCED_PARENTHESES
+ *
+ * Macro name is not followed by a balanced set of parentheses.
+ */
+static function_status_t
+_arguments_parse (argument_list_t *arguments,
+ token_node_t *node,
+ token_node_t **last)
+{
+ token_list_t *argument;
+ int paren_count;
+
+ node = node->next;
+
+ /* Ignore whitespace before first parenthesis. */
+ while (node && node->token->type == SPACE)
+ node = node->next;
+
+ if (node == NULL || node->token->type != '(')
+ return FUNCTION_NOT_A_FUNCTION;
+
+ node = node->next;
+
+ argument = _token_list_create (arguments);
+ _argument_list_append (arguments, argument);
+
+ for (paren_count = 1; node; node = node->next) {
+ if (node->token->type == '(')
+ {
+ paren_count++;
+ }
+ else if (node->token->type == ')')
+ {
+ paren_count--;
+ if (paren_count == 0)
+ break;
+ }
+
+ if (node->token->type == ',' &&
+ paren_count == 1)
+ {
+ _token_list_trim_trailing_space (argument);
+ argument = _token_list_create (arguments);
+ _argument_list_append (arguments, argument);
+ }
+ else {
+ if (argument->head == NULL) {
+ /* Don't treat initial whitespace as
+ * part of the arguement. */
+ if (node->token->type == SPACE)
+ continue;
+ }
+ _token_list_append (argument, node->token);
+ }
+ }
+
+ if (paren_count)
+ return FUNCTION_UNBALANCED_PARENTHESES;
+
+ *last = node;
+
+ return FUNCTION_STATUS_SUCCESS;
+}
+
+/* This is a helper function that's essentially part of the
+ * implementation of _glcpp_parser_expand_node. It shouldn't be called
+ * except for by that function.
+ *
+ * Returns NULL if node is a simple token with no expansion, (that is,
+ * although 'node' corresponds to an identifier defined as a
+ * function-like macro, it is not followed with a parenthesized
+ * argument list).
+ *
+ * Compute the complete expansion of node (which is a function-like
+ * macro) and subsequent nodes which are arguments.
+ *
+ * Returns the token list that results from the expansion and sets
+ * *last to the last node in the list that was consumed by the
+ * expansion. Specificallty, *last will be set as follows: as the
+ * token of the closing right parenthesis.
+ */
+static token_list_t *
+_glcpp_parser_expand_function (glcpp_parser_t *parser,
+ token_node_t *node,
+ token_node_t **last)
+
+{
+ macro_t *macro;
+ const char *identifier;
+ argument_list_t *arguments;
+ function_status_t status;
+ token_list_t *substituted;
+ int parameter_index;
+
+ identifier = node->token->value.str;
+
+ macro = hash_table_find (parser->defines, identifier);
+
+ assert (macro->is_function);
+
+ arguments = _argument_list_create (parser);
+ status = _arguments_parse (arguments, node, last);
+
+ switch (status) {
+ case FUNCTION_STATUS_SUCCESS:
+ break;
+ case FUNCTION_NOT_A_FUNCTION:
+ return NULL;
+ case FUNCTION_UNBALANCED_PARENTHESES:
+ glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier);
+ return NULL;
+ }
+
+ if (macro->replacements == NULL) {
+ talloc_free (arguments);
+ return _token_list_create (parser);
+ }
+
+ if (! ((_argument_list_length (arguments) ==
+ _string_list_length (macro->parameters)) ||
+ (_string_list_length (macro->parameters) == 0 &&
+ _argument_list_length (arguments) == 1 &&
+ arguments->head->argument->head == NULL)))
+ {
+ glcpp_error (&node->token->location, parser,
+ "Error: macro %s invoked with %d arguments (expected %d)\n",
+ identifier,
+ _argument_list_length (arguments),
+ _string_list_length (macro->parameters));
+ return NULL;
+ }
+
+ /* Perform argument substitution on the replacement list. */
+ substituted = _token_list_create (arguments);
+
+ for (node = macro->replacements->head; node; node = node->next)
+ {
+ if (node->token->type == IDENTIFIER &&
+ _string_list_contains (macro->parameters,
+ node->token->value.str,
+ ¶meter_index))
+ {
+ token_list_t *argument;
+ argument = _argument_list_member_at (arguments,
+ parameter_index);
+ /* Before substituting, we expand the argument
+ * tokens, or append a placeholder token for
+ * an empty argument. */
+ if (argument->head) {
+ _glcpp_parser_expand_token_list (parser,
+ argument);
+ _token_list_append_list (substituted, argument);
+ } else {
+ token_t *new_token;
+
+ new_token = _token_create_ival (substituted,
+ PLACEHOLDER,
+ PLACEHOLDER);
+ _token_list_append (substituted, new_token);
+ }
+ } else {
+ _token_list_append (substituted, node->token);
+ }
+ }
+
+ /* After argument substitution, and before further expansion
+ * below, implement token pasting. */
+
+ _token_list_trim_trailing_space (substituted);
+
+ node = substituted->head;
+ while (node)
+ {
+ token_node_t *next_non_space;
+
+ /* Look ahead for a PASTE token, skipping space. */
+ next_non_space = node->next;
+ while (next_non_space && next_non_space->token->type == SPACE)
+ next_non_space = next_non_space->next;
+
+ if (next_non_space == NULL)
+ break;
+
+ if (next_non_space->token->type != PASTE) {
+ node = next_non_space;
+ continue;
+ }
+
+ /* Now find the next non-space token after the PASTE. */
+ next_non_space = next_non_space->next;
+ while (next_non_space && next_non_space->token->type == SPACE)
+ next_non_space = next_non_space->next;
+
+ if (next_non_space == NULL) {
+ yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
+ return NULL;
+ }
+
+ node->token = _token_paste (parser, node->token, next_non_space->token);
+ node->next = next_non_space->next;
+ if (next_non_space == substituted->tail)
+ substituted->tail = node;
+
+ node = node->next;
+ }
+
+ substituted->non_space_tail = substituted->tail;
+
+ return substituted;
+}
+
+/* Compute the complete expansion of node, (and subsequent nodes after
+ * 'node' in the case that 'node' is a function-like macro and
+ * subsequent nodes are arguments).
+ *
+ * Returns NULL if node is a simple token with no expansion.
+ *
+ * Otherwise, returns the token list that results from the expansion
+ * and sets *last to the last node in the list that was consumed by
+ * the expansion. Specificallty, *last will be set as follows:
+ *
+ * As 'node' in the case of object-like macro expansion.
+ *
+ * As the token of the closing right parenthesis in the case of
+ * function-like macro expansion.
+ */
+static token_list_t *
+_glcpp_parser_expand_node (glcpp_parser_t *parser,
+ token_node_t *node,
+ token_node_t **last)
+{
+ token_t *token = node->token;
+ const char *identifier;
+ macro_t *macro;
+
+ /* We only expand identifiers */
+ if (token->type != IDENTIFIER) {
+ /* We change any COMMA into a COMMA_FINAL to prevent
+ * it being mistaken for an argument separator
+ * later. */
+ if (token->type == ',') {
+ token->type = COMMA_FINAL;
+ token->value.ival = COMMA_FINAL;
+ }
+
+ return NULL;
+ }
+
+ /* Look up this identifier in the hash table. */
+ identifier = token->value.str;
+ macro = hash_table_find (parser->defines, identifier);
+
+ /* Not a macro, so no expansion needed. */
+ if (macro == NULL)
+ return NULL;
+
+ /* Finally, don't expand this macro if we're already actively
+ * expanding it, (to avoid infinite recursion). */
+ if (_active_list_contains (parser->active, identifier)) {
+ /* We change the token type here from IDENTIFIER to
+ * OTHER to prevent any future expansion of this
+ * unexpanded token. */
+ char *str;
+ token_list_t *expansion;
+ token_t *final;
+
+ str = xtalloc_strdup (parser, token->value.str);
+ final = _token_create_str (parser, OTHER, str);
+ expansion = _token_list_create (parser);
+ _token_list_append (expansion, final);
+ *last = node;
+ return expansion;
+ }
+
+ if (! macro->is_function)
+ {
+ *last = node;
+
+ if (macro->replacements == NULL)
+ return _token_list_create (parser);
+
+ return _token_list_copy (parser, macro->replacements);
+ }
+
+ return _glcpp_parser_expand_function (parser, node, last);
+}
+
+/* Push a new identifier onto the active list, returning the new list.
+ *
+ * Here, 'marker' is the token node that appears in the list after the
+ * expansion of 'identifier'. That is, when the list iterator begins
+ * examinging 'marker', then it is time to pop this node from the
+ * active stack.
+ */
+active_list_t *
+_active_list_push (active_list_t *list,
+ const char *identifier,
+ token_node_t *marker)
+{
+ active_list_t *node;
+
+ node = xtalloc (list, active_list_t);
+ node->identifier = xtalloc_strdup (node, identifier);
+ node->marker = marker;
+ node->next = list;
+
+ return node;
+}
+
+active_list_t *
+_active_list_pop (active_list_t *list)
+{
+ active_list_t *node = list;
+
+ if (node == NULL)
+ return NULL;
+
+ node = list->next;
+ talloc_free (list);
+
+ return node;
+}
+
+int
+_active_list_contains (active_list_t *list, const char *identifier)
+{
+ active_list_t *node;
+
+ if (list == NULL)
+ return 0;
+
+ for (node = list; node; node = node->next)
+ if (strcmp (node->identifier, identifier) == 0)
+ return 1;
+
+ return 0;
+}
+
+/* Walk over the token list replacing nodes with their expansion.
+ * Whenever nodes are expanded the walking will walk over the new
+ * nodes, continuing to expand as necessary. The results are placed in
+ * 'list' itself;
+ */
+static void
+_glcpp_parser_expand_token_list (glcpp_parser_t *parser,
+ token_list_t *list)
+{
+ token_node_t *node_prev;
+ token_node_t *node, *last = NULL;
+ token_list_t *expansion;
+
+ if (list == NULL)
+ return;
+
+ _token_list_trim_trailing_space (list);
+
+ node_prev = NULL;
+ node = list->head;
+
+ while (node) {
+
+ while (parser->active && parser->active->marker == node)
+ parser->active = _active_list_pop (parser->active);
+
+ /* Find the expansion for node, which will replace all
+ * nodes from node to last, inclusive. */
+ expansion = _glcpp_parser_expand_node (parser, node, &last);
+ if (expansion) {
+ token_node_t *n;
+
+ for (n = node; n != last->next; n = n->next)
+ while (parser->active &&
+ parser->active->marker == n)
+ {
+ parser->active = _active_list_pop (parser->active);
+ }
+
+ parser->active = _active_list_push (parser->active,
+ node->token->value.str,
+ last->next);
+
+ /* Splice expansion into list, supporting a
+ * simple deletion if the expansion is
+ * empty. */
+ if (expansion->head) {
+ if (node_prev)
+ node_prev->next = expansion->head;
+ else
+ list->head = expansion->head;
+ expansion->tail->next = last->next;
+ if (last == list->tail)
+ list->tail = expansion->tail;
+ } else {
+ if (node_prev)
+ node_prev->next = last->next;
+ else
+ list->head = last->next;
+ if (last == list->tail)
+ list->tail = NULL;
+ }
+ } else {
+ node_prev = node;
+ }
+ node = node_prev ? node_prev->next : list->head;
+ }
+
+ while (parser->active)
+ parser->active = _active_list_pop (parser->active);
+
+ list->non_space_tail = list->tail;
+}
+
+void
+_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
+ token_list_t *list)
+{
+ if (list == NULL)
+ return;
+
+ _glcpp_parser_expand_token_list (parser, list);
+
+ _token_list_trim_trailing_space (list);
+
+ _token_list_print (parser, list);
+}
+
+void
+_check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
+ const char *identifier)
+{
+ /* According to the GLSL specification, macro names starting with "__"
+ * or "GL_" are reserved for future use. So, don't allow them.
+ */
+ if (strncmp(identifier, "__", 2) == 0) {
+ glcpp_error (loc, parser, "Macro names starting with \"__\" are reserved.\n");
+ }
+ if (strncmp(identifier, "GL_", 3) == 0) {
+ glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n");
+ }
+}
+
+void
+_define_object_macro (glcpp_parser_t *parser,
+ YYLTYPE *loc,
+ const char *identifier,
+ token_list_t *replacements)
+{
+ macro_t *macro;
+
+ _check_for_reserved_macro_name(parser, loc, identifier);
+
+ macro = xtalloc (parser, macro_t);
+
+ macro->is_function = 0;
+ macro->parameters = NULL;
+ macro->identifier = talloc_strdup (macro, identifier);
+ macro->replacements = talloc_steal (macro, replacements);
+
+ hash_table_insert (parser->defines, macro, identifier);
+}
+
+void
+_define_function_macro (glcpp_parser_t *parser,
+ YYLTYPE *loc,
+ const char *identifier,
+ string_list_t *parameters,
+ token_list_t *replacements)
+{
+ macro_t *macro;
+
+ _check_for_reserved_macro_name(parser, loc, identifier);
+
+ macro = xtalloc (parser, macro_t);
+
+ macro->is_function = 1;
+ macro->parameters = talloc_steal (macro, parameters);
+ macro->identifier = talloc_strdup (macro, identifier);
+ macro->replacements = talloc_steal (macro, replacements);
+
+ hash_table_insert (parser->defines, macro, identifier);
+}
+
+static int
+glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
+{
+ token_node_t *node;
+ int ret;
+
+ if (parser->lex_from_list == NULL) {
+ ret = glcpp_lex (yylval, yylloc, parser->scanner);
+
+ /* XXX: This ugly block of code exists for the sole
+ * purpose of converting a NEWLINE token into a SPACE
+ * token, but only in the case where we have seen a
+ * function-like macro name, but have not yet seen its
+ * closing parenthesis.
+ *
+ * There's perhaps a more compact way to do this with
+ * mid-rule actions in the grammar.
+ *
+ * I'm definitely not pleased with the complexity of
+ * this code here.
+ */
+ if (parser->newline_as_space)
+ {
+ if (ret == '(') {
+ parser->paren_count++;
+ } else if (ret == ')') {
+ parser->paren_count--;
+ if (parser->paren_count == 0)
+ parser->newline_as_space = 0;
+ } else if (ret == NEWLINE) {
+ ret = SPACE;
+ } else if (ret != SPACE) {
+ if (parser->paren_count == 0)
+ parser->newline_as_space = 0;
+ }
+ }
+ else if (parser->in_control_line)
+ {
+ if (ret == NEWLINE)
+ parser->in_control_line = 0;
+ }
+ else if (ret == HASH_DEFINE_OBJ || ret == HASH_DEFINE_FUNC ||
+ ret == HASH_UNDEF || ret == HASH_IF ||
+ ret == HASH_IFDEF || ret == HASH_IFNDEF ||
+ ret == HASH_ELIF || ret == HASH_ELSE ||
+ ret == HASH_ENDIF || ret == HASH)
+ {
+ parser->in_control_line = 1;
+ }
+ else if (ret == IDENTIFIER)
+ {
+ macro_t *macro;
+ macro = hash_table_find (parser->defines,
+ yylval->str);
+ if (macro && macro->is_function) {
+ parser->newline_as_space = 1;
+ parser->paren_count = 0;
+ }
+ }
+
+ return ret;
+ }
+
+ node = parser->lex_from_node;
+
+ if (node == NULL) {
+ talloc_free (parser->lex_from_list);
+ parser->lex_from_list = NULL;
+ return NEWLINE;
+ }
+
+ *yylval = node->token->value;
+ ret = node->token->type;
+
+ parser->lex_from_node = node->next;
+
+ return ret;
+}
+
+static void
+glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list)
+{
+ token_node_t *node;
+
+ assert (parser->lex_from_list == NULL);
+
+ /* Copy list, eliminating any space tokens. */
+ parser->lex_from_list = _token_list_create (parser);
+
+ for (node = list->head; node; node = node->next) {
+ if (node->token->type == SPACE)
+ continue;
+ _token_list_append (parser->lex_from_list, node->token);
+ }
+
+ talloc_free (list);
+
+ parser->lex_from_node = parser->lex_from_list->head;
+
+ /* It's possible the list consisted of nothing but whitespace. */
+ if (parser->lex_from_node == NULL) {
+ talloc_free (parser->lex_from_list);
+ parser->lex_from_list = NULL;
+ }
+}
+
+static void
+_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
+ int condition)
+{
+ skip_type_t current = SKIP_NO_SKIP;
+ skip_node_t *node;
+
+ if (parser->skip_stack)
+ current = parser->skip_stack->type;
+
+ node = xtalloc (parser, skip_node_t);
+ node->loc = *loc;
+
+ if (current == SKIP_NO_SKIP) {
+ if (condition)
+ node->type = SKIP_NO_SKIP;
+ else
+ node->type = SKIP_TO_ELSE;
+ } else {
+ node->type = SKIP_TO_ENDIF;
+ }
+
+ node->next = parser->skip_stack;
+ parser->skip_stack = node;
+}
+
+static void
+_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
+ const char *type, int condition)
+{
+ if (parser->skip_stack == NULL) {
+ glcpp_error (loc, parser, "%s without #if\n", type);
+ return;
+ }
+
+ if (parser->skip_stack->type == SKIP_TO_ELSE) {
+ if (condition)
+ parser->skip_stack->type = SKIP_NO_SKIP;
+ } else {
+ parser->skip_stack->type = SKIP_TO_ENDIF;
+ }
+}
+
+static void
+_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc)
+{
+ skip_node_t *node;
+
+ if (parser->skip_stack == NULL) {
+ glcpp_error (loc, parser, "#endif without #if\n");
+ return;
+ }
+
+ node = parser->skip_stack;
+ parser->skip_stack = node->next;
+ talloc_free (node);
+}
--- /dev/null
+/*
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "glcpp.h"
+
+extern int yydebug;
+
+static char *
+load_text_file(void *ctx, const char *file_name)
+{
+ char *text = NULL;
+ struct stat st;
+ ssize_t total_read = 0;
+ int fd = file_name == NULL ? STDIN_FILENO : open(file_name, O_RDONLY);
+
+ if (fd < 0) {
+ return NULL;
+ }
+
+ if (fstat(fd, & st) == 0) {
+ text = (char *) talloc_size(ctx, st.st_size + 1);
+ if (text != NULL) {
+ do {
+ ssize_t bytes = read(fd, text + total_read,
+ st.st_size - total_read);
+ if (bytes < 0) {
+ text = NULL;
+ break;
+ }
+
+ if (bytes == 0) {
+ break;
+ }
+
+ total_read += bytes;
+ } while (total_read < st.st_size);
+
+ text[total_read] = '\0';
+ }
+ }
+
+ close(fd);
+
+ return text;
+}
+
+int
+preprocess(void *talloc_ctx, const char **shader, char **info_log);
+
+int
+main (void)
+{
+ void *ctx = talloc(NULL, void*);
+ const char *shader = load_text_file(ctx, NULL);
+ char *info_log = talloc_strdup(ctx, "");
+ int ret = preprocess(ctx, &shader, &info_log);
+
+ printf("%s", shader);
+ fprintf(stderr, "%s", info_log);
+
+ talloc_free(ctx);
+
+ return ret;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef GLCPP_H
+#define GLCPP_H
+
+#include <stdint.h>
+
+#include <talloc.h>
+
+#include "hash_table.h"
+
+#define yyscan_t void*
+
+/* Some data types used for parser values. */
+
+typedef struct string_node {
+ const char *str;
+ struct string_node *next;
+} string_node_t;
+
+typedef struct string_list {
+ string_node_t *head;
+ string_node_t *tail;
+} string_list_t;
+
+typedef struct token token_t;
+typedef struct token_list token_list_t;
+
+typedef union YYSTYPE
+{
+ intmax_t ival;
+ char *str;
+ string_list_t *string_list;
+ token_t *token;
+ token_list_t *token_list;
+} YYSTYPE;
+
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+
+typedef struct YYLTYPE {
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ unsigned source;
+} YYLTYPE;
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+
+struct token {
+ int type;
+ YYSTYPE value;
+ YYLTYPE location;
+};
+
+typedef struct token_node {
+ token_t *token;
+ struct token_node *next;
+} token_node_t;
+
+struct token_list {
+ token_node_t *head;
+ token_node_t *tail;
+ token_node_t *non_space_tail;
+};
+
+typedef struct argument_node {
+ token_list_t *argument;
+ struct argument_node *next;
+} argument_node_t;
+
+typedef struct argument_list {
+ argument_node_t *head;
+ argument_node_t *tail;
+} argument_list_t;
+
+typedef struct glcpp_parser glcpp_parser_t;
+
+typedef enum {
+ TOKEN_CLASS_IDENTIFIER,
+ TOKEN_CLASS_IDENTIFIER_FINALIZED,
+ TOKEN_CLASS_FUNC_MACRO,
+ TOKEN_CLASS_OBJ_MACRO
+} token_class_t;
+
+token_class_t
+glcpp_parser_classify_token (glcpp_parser_t *parser,
+ const char *identifier,
+ int *parameter_index);
+
+typedef struct {
+ int is_function;
+ string_list_t *parameters;
+ const char *identifier;
+ token_list_t *replacements;
+} macro_t;
+
+typedef struct expansion_node {
+ macro_t *macro;
+ token_node_t *replacements;
+ struct expansion_node *next;
+} expansion_node_t;
+
+typedef enum skip_type {
+ SKIP_NO_SKIP,
+ SKIP_TO_ELSE,
+ SKIP_TO_ENDIF
+} skip_type_t;
+
+typedef struct skip_node {
+ skip_type_t type;
+ YYLTYPE loc; /* location of the initial #if/#elif/... */
+ struct skip_node *next;
+} skip_node_t;
+
+typedef struct active_list {
+ const char *identifier;
+ token_node_t *marker;
+ struct active_list *next;
+} active_list_t;
+
+struct glcpp_parser {
+ yyscan_t scanner;
+ struct hash_table *defines;
+ active_list_t *active;
+ int lexing_if;
+ int space_tokens;
+ int newline_as_space;
+ int in_control_line;
+ int paren_count;
+ skip_node_t *skip_stack;
+ token_list_t *lex_from_list;
+ token_node_t *lex_from_node;
+ char *output;
+ char *info_log;
+ int error;
+};
+
+glcpp_parser_t *
+glcpp_parser_create (void);
+
+int
+glcpp_parser_parse (glcpp_parser_t *parser);
+
+void
+glcpp_parser_destroy (glcpp_parser_t *parser);
+
+int
+preprocess(void *talloc_ctx, const char **shader, char **info_log);
+
+/* Functions for writing to the info log */
+
+void
+glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
+
+void
+glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
+
+/* Generated by glcpp-lex.l to glcpp-lex.c */
+
+int
+glcpp_lex_init_extra (glcpp_parser_t *parser, yyscan_t* scanner);
+
+void
+glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader);
+
+int
+glcpp_lex (YYSTYPE *lvalp, YYLTYPE *llocp, yyscan_t scanner);
+
+int
+glcpp_lex_destroy (yyscan_t scanner);
+
+/* Generated by glcpp-parse.y to glcpp-parse.c */
+
+int
+yyparse (glcpp_parser_t *parser);
+
+/* xtalloc - wrappers around talloc to check for out-of-memory */
+
+#define xtalloc(ctx, type) (type *)xtalloc_named_const(ctx, sizeof(type), #type)
+
+#define xtalloc_size(ctx, size) xtalloc_named_const(ctx, size, __location__)
+
+void *
+xtalloc_named_const (const void *context, size_t size, const char *name);
+
+char *
+xtalloc_strdup (const void *t, const char *p);
+
+char *
+xtalloc_strndup (const void *t, const char *p, size_t n);
+
+char *
+xtalloc_asprintf (const void *t, const char *fmt, ...);
+
+void *
+_xtalloc_reference_loc (const void *context,
+ const void *ptr, const char *location);
+
+#define xtalloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_xtalloc_reference_loc((ctx),(ptr), __location__)
+
+#endif
--- /dev/null
+/*
+ * Copyright © 2008 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.
+ */
+
+/**
+ * \file hash_table.c
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "hash_table.h"
+
+struct node {
+ struct node *next;
+ struct node *prev;
+};
+
+struct hash_table {
+ hash_func_t hash;
+ hash_compare_func_t compare;
+
+ unsigned num_buckets;
+ struct node buckets[1];
+};
+
+
+struct hash_node {
+ struct node link;
+ const void *key;
+ void *data;
+};
+
+
+struct hash_table *
+hash_table_ctor(unsigned num_buckets, hash_func_t hash,
+ hash_compare_func_t compare)
+{
+ struct hash_table *ht;
+ unsigned i;
+
+
+ if (num_buckets < 16) {
+ num_buckets = 16;
+ }
+
+ ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1)
+ * sizeof(ht->buckets[0])));
+ if (ht != NULL) {
+ ht->hash = hash;
+ ht->compare = compare;
+ ht->num_buckets = num_buckets;
+
+ for (i = 0; i < num_buckets; i++) {
+ make_empty_list(& ht->buckets[i]);
+ }
+ }
+
+ return ht;
+}
+
+
+void
+hash_table_dtor(struct hash_table *ht)
+{
+ hash_table_clear(ht);
+ _mesa_free(ht);
+}
+
+
+void
+hash_table_clear(struct hash_table *ht)
+{
+ struct node *node;
+ struct node *temp;
+ unsigned i;
+
+
+ for (i = 0; i < ht->num_buckets; i++) {
+ foreach_s(node, temp, & ht->buckets[i]) {
+ remove_from_list(node);
+ _mesa_free(node);
+ }
+
+ assert(is_empty_list(& ht->buckets[i]));
+ }
+}
+
+
+void *
+hash_table_find(struct hash_table *ht, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct node *node;
+
+ foreach(node, & ht->buckets[bucket]) {
+ struct hash_node *hn = (struct hash_node *) node;
+
+ if ((*ht->compare)(hn->key, key) == 0) {
+ return hn->data;
+ }
+ }
+
+ return NULL;
+}
+
+
+void
+hash_table_insert(struct hash_table *ht, void *data, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct hash_node *node;
+
+ node = _mesa_calloc(sizeof(*node));
+
+ node->data = data;
+ node->key = key;
+
+ insert_at_head(& ht->buckets[bucket], & node->link);
+}
+
+
+unsigned
+hash_table_string_hash(const void *key)
+{
+ const char *str = (const char *) key;
+ unsigned hash = 5381;
+
+
+ while (*str != '\0') {
+ hash = (hash * 33) + *str;
+ str++;
+ }
+
+ return hash;
+}
--- /dev/null
+/*
+ * Copyright © 2008 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.
+ */
+
+/**
+ * \file hash_table.h
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#ifndef HASH_TABLE_H
+#define HASH_TABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+
+struct hash_table;
+
+typedef unsigned (*hash_func_t)(const void *key);
+typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
+
+/**
+ * Hash table constructor
+ *
+ * Creates a hash table with the specified number of buckets. The supplied
+ * \c hash and \c compare routines are used when adding elements to the table
+ * and when searching for elements in the table.
+ *
+ * \param num_buckets Number of buckets (bins) in the hash table.
+ * \param hash Function used to compute hash value of input keys.
+ * \param compare Function used to compare keys.
+ */
+extern struct hash_table *hash_table_ctor(unsigned num_buckets,
+ hash_func_t hash, hash_compare_func_t compare);
+
+
+/**
+ * Release all memory associated with a hash table
+ *
+ * \warning
+ * This function cannot release memory occupied either by keys or data.
+ */
+extern void hash_table_dtor(struct hash_table *ht);
+
+
+/**
+ * Flush all entries from a hash table
+ *
+ * \param ht Table to be cleared of its entries.
+ */
+extern void hash_table_clear(struct hash_table *ht);
+
+
+/**
+ * Search a hash table for a specific element
+ *
+ * \param ht Table to be searched
+ * \param key Key of the desired element
+ *
+ * \return
+ * The \c data value supplied to \c hash_table_insert when the element with
+ * the matching key was added. If no matching key exists in the table,
+ * \c NULL is returned.
+ */
+extern void *hash_table_find(struct hash_table *ht, const void *key);
+
+
+/**
+ * Add an element to a hash table
+ */
+extern void hash_table_insert(struct hash_table *ht, void *data,
+ const void *key);
+
+
+/**
+ * Compute hash value of a string
+ *
+ * Computes the hash value of a string using the DJB2 algorithm developed by
+ * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
+ * a time. I was unable to find the original posting in the archives.
+ *
+ * \param key Pointer to a NUL terminated string to be hashed.
+ *
+ * \sa hash_table_string_compare
+ */
+extern unsigned hash_table_string_hash(const void *key);
+
+
+/**
+ * Compare two strings used as keys
+ *
+ * This is just a macro wrapper around \c strcmp.
+ *
+ * \sa hash_table_string_hash
+ */
+#define hash_table_string_compare ((hash_compare_func_t) strcmp)
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* HASH_TABLE_H */
--- /dev/null
+#include <assert.h>
+#include <stdlib.h>
+
+#define _mesa_malloc(x) malloc(x)
+#define _mesa_free(x) free(x)
+#define _mesa_calloc(x) calloc(1,x)
--- /dev/null
+/**
+ * \file simple_list.h
+ * Simple macros for type-safe, intrusive lists.
+ *
+ * Intended to work with a list sentinal which is created as an empty
+ * list. Insert & delete are O(1).
+ *
+ * \author
+ * (C) 1997, Keith Whitwell
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 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.
+ */
+
+
+#ifndef _SIMPLE_LIST_H
+#define _SIMPLE_LIST_H
+
+struct simple_node {
+ struct simple_node *next;
+ struct simple_node *prev;
+};
+
+/**
+ * Remove an element from list.
+ *
+ * \param elem element to remove.
+ */
+#define remove_from_list(elem) \
+do { \
+ (elem)->next->prev = (elem)->prev; \
+ (elem)->prev->next = (elem)->next; \
+} while (0)
+
+/**
+ * Insert an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_head(list, elem) \
+do { \
+ (elem)->prev = list; \
+ (elem)->next = (list)->next; \
+ (list)->next->prev = elem; \
+ (list)->next = elem; \
+} while(0)
+
+/**
+ * Insert an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_tail(list, elem) \
+do { \
+ (elem)->next = list; \
+ (elem)->prev = (list)->prev; \
+ (list)->prev->next = elem; \
+ (list)->prev = elem; \
+} while(0)
+
+/**
+ * Move an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_head(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_head(list, elem); \
+} while (0)
+
+/**
+ * Move an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_tail(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_tail(list, elem); \
+} while (0)
+
+/**
+ * Consatinate a cyclic list to a list
+ *
+ * Appends the sequence of nodes starting with \c tail to the list \c head.
+ * A "cyclic list" is a list that does not have a sentinal node. This means
+ * that the data pointed to by \c tail is an actual node, not a dataless
+ * sentinal. Note that if \c tail constist of a single node, this macro
+ * behaves identically to \c insert_at_tail
+ *
+ * \param head Head of the list to be appended to. This may or may not
+ * be a cyclic list.
+ * \param tail Head of the cyclic list to be appended to \c head.
+ * \param temp Temporary \c simple_list used by the macro
+ *
+ * \sa insert_at_tail
+ */
+#define concat_list_and_cycle(head, tail, temp) \
+do { \
+ (head)->prev->next = (tail); \
+ (tail)->prev->next = (head); \
+ (temp) = (head)->prev; \
+ (head)->prev = (tail)->prev; \
+ (tail)->prev = (temp); \
+} while (0)
+
+#define concat_list(head, next_list) \
+do { \
+ (next_list)->next->prev = (head)->prev; \
+ (next_list)->prev->next = (head); \
+ (head)->prev->next = (next_list)->next; \
+ (head)->prev = (next_list)->prev; \
+} while (0)
+
+/**
+ * Make a empty list empty.
+ *
+ * \param sentinal list (sentinal element).
+ */
+#define make_empty_list(sentinal) \
+do { \
+ (sentinal)->next = sentinal; \
+ (sentinal)->prev = sentinal; \
+} while (0)
+
+/**
+ * Get list first element.
+ *
+ * \param list list.
+ *
+ * \return pointer to first element.
+ */
+#define first_elem(list) ((list)->next)
+
+/**
+ * Get list last element.
+ *
+ * \param list list.
+ *
+ * \return pointer to last element.
+ */
+#define last_elem(list) ((list)->prev)
+
+/**
+ * Get next element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to next element.
+ */
+#define next_elem(elem) ((elem)->next)
+
+/**
+ * Get previous element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to previous element.
+ */
+#define prev_elem(elem) ((elem)->prev)
+
+/**
+ * Test whether element is at end of the list.
+ *
+ * \param list list.
+ * \param elem element.
+ *
+ * \return non-zero if element is at end of list, or zero otherwise.
+ */
+#define at_end(list, elem) ((elem) == (list))
+
+/**
+ * Test if a list is empty.
+ *
+ * \param list list.
+ *
+ * \return non-zero if list empty, or zero otherwise.
+ */
+#define is_empty_list(list) ((list)->next == (list))
+
+/**
+ * Walk through the elements of a list.
+ *
+ * \param ptr pointer to the current element.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach(ptr, list) \
+ for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next )
+
+/**
+ * Walk through the elements of a list.
+ *
+ * Same as #foreach but lets you unlink the current value during a list
+ * traversal. Useful for freeing a list, element by element.
+ *
+ * \param ptr pointer to the current element.
+ * \param t temporary pointer.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach_s(ptr, t, list) \
+ for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
+
+#endif
--- /dev/null
+/*
+ * 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 <assert.h>
+#include <ctype.h>
+#include "glcpp.h"
+
+void
+glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
+{
+ parser->error = 1;
+ parser->info_log = talloc_asprintf_append(parser->info_log,
+ "%u:%u(%u): "
+ "preprocessor error: ",
+ locp->source,
+ locp->first_line,
+ locp->first_column);
+ va_list ap;
+ va_start(ap, fmt);
+ parser->info_log = talloc_vasprintf_append(parser->info_log, fmt, ap);
+ va_end(ap);
+ parser->info_log = talloc_strdup_append(parser->info_log, "\n");
+}
+
+void
+glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
+{
+ parser->info_log = talloc_asprintf_append(parser->info_log,
+ "%u:%u(%u): "
+ "preprocessor warning: ",
+ locp->source,
+ locp->first_line,
+ locp->first_column);
+ va_list ap;
+ va_start(ap, fmt);
+ parser->info_log = talloc_vasprintf_append(parser->info_log, fmt, ap);
+ va_end(ap);
+ parser->info_log = talloc_strdup_append(parser->info_log, "\n");
+}
+
+/* Searches backwards for '^ *#' from a given starting point. */
+static int
+in_directive(const char *shader, const char *ptr)
+{
+ assert(ptr >= shader);
+
+ /* Search backwards for '#'. If we find a \n first, it doesn't count */
+ for (; ptr >= shader && *ptr != '#'; ptr--) {
+ if (*ptr == '\n')
+ return 0;
+ }
+ if (ptr >= shader) {
+ /* Found '#'...look for spaces preceded by a newline */
+ for (ptr--; ptr >= shader && isblank(*ptr); ptr--);
+ // FIXME: I don't think the '\n' case can happen
+ if (ptr < shader || *ptr == '\n')
+ return 1;
+ }
+ return 0;
+}
+
+/* Remove any line continuation characters in preprocessing directives.
+ * However, ignore any in GLSL code, as "There is no line continuation
+ * character" (1.30 page 9) in GLSL.
+ */
+static char *
+remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
+{
+ int in_continued_line = 0;
+ int extra_newlines = 0;
+ char *clean = talloc_strdup(ctx, "");
+ const char *search_start = shader;
+ const char *newline;
+ while ((newline = strchr(search_start, '\n')) != NULL) {
+ const char *backslash = NULL;
+ /* Find the preceding '\', if it exists */
+ if (newline[-1] == '\\') {
+ backslash = newline - 1;
+ } else if (newline[-1] == '\r' && newline[-2] == '\\') {
+ backslash = newline - 2;
+ }
+ /* Double backslashes don't count (the backslash is escaped) */
+ if (backslash != NULL && backslash[-1] == '\\') {
+ backslash = NULL;
+ }
+
+ if (backslash != NULL) {
+ /* We found a line continuation, but do we care? */
+ if (!in_continued_line) {
+ if (in_directive(shader, backslash)) {
+ in_continued_line = 1;
+ extra_newlines = 0;
+ }
+ }
+ if (in_continued_line) {
+ /* Copy everything before the \ */
+ clean = talloc_strndup_append(clean, shader, backslash - shader);
+ shader = newline + 1;
+ extra_newlines++;
+ }
+ } else if (in_continued_line) {
+ /* Copy everything up to and including the \n */
+ clean = talloc_strndup_append(clean, shader, newline - shader + 1);
+ shader = newline + 1;
+ /* Output extra newlines to make line numbers match */
+ for (; extra_newlines > 0; extra_newlines--)
+ clean = talloc_strdup_append(clean, "\n");
+ in_continued_line = 0;
+ }
+ search_start = newline + 1;
+ }
+ clean = talloc_strdup_append(clean, shader);
+ return clean;
+}
+
+extern int
+preprocess(void *talloc_ctx, const char **shader, char **info_log)
+{
+ int errors;
+ glcpp_parser_t *parser = glcpp_parser_create ();
+ *shader = remove_line_continuations(parser, *shader);
+
+ glcpp_lex_set_source_string (parser, *shader);
+
+ glcpp_parser_parse (parser);
+
+ *info_log = talloc_strdup_append(*info_log, parser->info_log);
+
+ talloc_steal(talloc_ctx, parser->output);
+ *shader = parser->output;
+
+ errors = parser->error;
+ glcpp_parser_destroy (parser);
+ return errors;
+}
--- /dev/null
+this is four tokens
--- /dev/null
+this is four tokens
+
--- /dev/null
+#define foo 1
+foo
--- /dev/null
+#define foo 1
+#define bar foo
+bar
--- /dev/null
+#define bar foo
+#define foo 1
+bar
--- /dev/null
+#define foo bar
+#define bar baz
+#define baz foo
+foo
+bar
+baz
--- /dev/null
+
+
+
+foo
+bar
+baz
+
--- /dev/null
+#define foo 1
+#define bar a foo
+bar
--- /dev/null
+#define bar a foo
+#define foo 1
+bar
--- /dev/null
+#define foo a bar
+#define bar b baz
+#define baz c foo
+foo
+bar
+baz
--- /dev/null
+
+
+
+a b c foo
+b c a bar
+c a b baz
+
--- /dev/null
+#define foo
+foo
--- /dev/null
+#define foo 1
+foo
+#undef foo
+foo
--- /dev/null
+
+1
+
+foo
+
--- /dev/null
+#define foo 1
+foo
+#undef foo
+foo
+#define foo 2
+foo
--- /dev/null
+
+1
+
+foo
+
+2
+
--- /dev/null
+#define foo()
+foo()
--- /dev/null
+#define foo() bar
+foo()
--- /dev/null
+#define foo(x) 1
+foo(bar)
--- /dev/null
+#define foo(x,y) 1
+foo(bar,baz)
--- /dev/null
+#define foo ()1
+foo()
+#define bar ()2
+bar()
--- /dev/null
+
+()1()
+
+()2()
+
--- /dev/null
+#define foo(x) ((x)+1)
+foo(bar)
--- /dev/null
+
+((bar)+1)
+
--- /dev/null
+#define foo(x,y) ((x)*(y))
+foo(bar,baz)
--- /dev/null
+
+((bar)*(baz))
+
--- /dev/null
+#define x 0
+#define foo(x) x
+foo(1)
--- /dev/null
+#define foo(x) (x)
+foo(this is more than one word)
--- /dev/null
+
+(this is more than one word)
+
--- /dev/null
+#define foo(x,y) x,two fish,red fish,y
+foo(one fish, blue fish)
--- /dev/null
+
+one fish,two fish,red fish,blue fish
+
--- /dev/null
+#define bar(x) (1+(x))
+#define foo(y) (2*(y))
+foo(bar(3))
--- /dev/null
+
+
+(2*((1+(3))))
+
--- /dev/null
+#define foo(x) (x)
+foo(argument(including parens)for the win)
--- /dev/null
+
+(argument(including parens)for the win)
+
--- /dev/null
+#define noargs() 1
+# define onearg(foo) foo
+ # define twoargs( x , y ) x y
+ # define threeargs( a , b , c ) a b c
+noargs ( )
+onearg ( 2 )
+twoargs ( 3 , 4 )
+threeargs ( 5 , 6 , 7 )
--- /dev/null
+
+
+
+
+1
+2
+3 4
+5 6 7
+
--- /dev/null
+#define foo foo
+#define bar foo
+bar
--- /dev/null
+#define foo(bar) bar
+foo bar
--- /dev/null
+
+foo bar
+
--- /dev/null
+#define foo(a) bar
+
+foo
+(
+1
+)
--- /dev/null
+#define failure() success
+#define foo failure()
+foo
--- /dev/null
+
+
+success
+
--- /dev/null
+#define success() failure
+#define foo success
+foo
--- /dev/null
+
+
+success
+
--- /dev/null
+#define bar(failure) failure
+#define foo bar(success)
+foo
--- /dev/null
+
+
+success
+
--- /dev/null
+#define baz(failure) failure
+#define bar(failure) failure
+#define foo bar(baz(success))
+foo
--- /dev/null
+
+
+
+success
+
--- /dev/null
+#define baz(failure) failure
+#define bar(failure) failure
+#define foo() bar(baz(success))
+foo()
--- /dev/null
+
+
+
+success
+
--- /dev/null
+#define foo(a) foo(2*(a))
+foo(3)
--- /dev/null
+
+foo(2*(3))
+
--- /dev/null
+#define foo(a) foo(2*(a))
+foo(foo(3))
--- /dev/null
+
+foo(2*(foo(2*(3))))
+
--- /dev/null
+#define foo(bar) bar
+foo(foo)
--- /dev/null
+#define foo(bar) bar
+foo(1+foo)
--- /dev/null
+#define bar success
+#define foo(x) x
+foo(more bar)
--- /dev/null
+
+
+more success
+
--- /dev/null
+#define expand(x) expand(x once)
+#define foo(x) x
+foo(expand(just))
--- /dev/null
+
+
+expand(just once)
+
--- /dev/null
+#define foo(x) success
+foo(argument (with,embedded , commas) -- tricky)
--- /dev/null
+
+success
+
--- /dev/null
+#define foo(a) (a)
+#define bar two,words
+foo(bar)
--- /dev/null
+
+
+(two,words)
+
--- /dev/null
+#define paste(a,b) a ## b
+paste(one , token)
--- /dev/null
+
+onetoken
+
--- /dev/null
+success_1
+#if 0
+failure
+#endif
+success_2
--- /dev/null
+success_1
+
+
+
+success_2
+
--- /dev/null
+success_1
+#if 1
+success_2
+#endif
+success_3
--- /dev/null
+success_1
+
+success_2
+
+success_3
+
--- /dev/null
+success_1
+#if 0
+failure
+#else
+success_2
+#endif
+success_3
--- /dev/null
+success_1
+
+
+
+success_2
+
+success_3
+
--- /dev/null
+success_1
+#if 1
+success_2
+#else
+failure
+#endif
+success_3
--- /dev/null
+success_1
+
+success_2
+
+
+
+success_3
+
--- /dev/null
+success_1
+#if 0
+failure_1
+#elif 0
+failure_2
+#elif 1
+success_3
+#elif 1
+failure_3
+#endif
+success_4
--- /dev/null
+success_1
+
+
+
+
+
+success_3
+
+
+
+success_4
+
--- /dev/null
+success_1
+#if 1
+success_2
+#elif 0
+failure_1
+#elif 1
+failure_2
+#elif 0
+failure_3
+#endif
+success_3
--- /dev/null
+success_1
+
+success_2
+
+
+
+
+
+
+
+success_3
+
--- /dev/null
+success_1
+#if 0
+failure_1
+#elif 0
+failure_2
+#elif 0
+failure_3
+#else
+success_2
+#endif
+success_3
--- /dev/null
+success_1
+
+
+
+
+
+
+
+success_2
+
+success_3
+
--- /dev/null
+success_1
+#if 0
+failure_1
+#if 1
+failure_2
+#else
+failure_3
+#endif
+failure_4
+#endif
+success_2
--- /dev/null
+success_1
+
+
+
+
+
+
+
+
+
+success_2
+
--- /dev/null
+#if 1 + 2 * 3 + - (25 % 17 - + 1)
+failure with operator precedence
+#else
+success
+#endif
--- /dev/null
+
+
+
+success
+
+
--- /dev/null
+#if defined foo
+failure_1
+#else
+success_1
+#endif
+#define foo
+#if defined foo
+success_2
+#else
+failure_2
+#endif
+#undef foo
+#if defined foo
+failure_3
+#else
+success_3
+#endif
--- /dev/null
+
+
+
+success_1
+
+
+
+success_2
+
+
+
+
+
+
+
+success_3
+
+
--- /dev/null
+#if 3 < 2
+failure_1
+#else
+success_1
+#endif
+
+#if 3 >= 2
+success_2
+#else
+failure_2
+#endif
+
+#if 2 + 3 <= 5
+success_3
+#else
+failure_3
+#endif
+
+#if 3 - 2 == 1
+success_3
+#else
+failure_3
+#endif
+
+#if 1 > 3
+failure_4
+#else
+success_4
+#endif
+
+#if 1 != 5
+success_5
+#else
+failure_5
+#endif
--- /dev/null
+
+
+
+success_1
+
+
+
+success_2
+
+
+
+
+
+success_3
+
+
+
+
+
+success_3
+
+
+
+
+
+
+
+success_4
+
+
+
+success_5
+
+
+
+
--- /dev/null
+#if (0xaaaaaaaa | 0x55555555) != 4294967295
+failure_1
+#else
+success_1
+#endif
+#if (0x12345678 ^ 0xfdecba98) == 4023971040
+success_2
+#else
+failure_2
+#endif
+#if (~ 0xdeadbeef) != -3735928560
+failure_3
+#else
+success_3
+#endif
+#if (0667 & 0733) == 403
+success_4
+#else
+failure_4
+#endif
--- /dev/null
+
+
+
+success_1
+
+
+success_2
+
+
+
+
+
+
+success_3
+
+
+success_4
+
+
+
+
--- /dev/null
+#if (15 / 2) != 7
+failure_1
+#else
+success_1
+#endif
+#if (1 << 12) == 4096
+success_2
+#else
+failure_2
+#endif
+#if (31762 >> 8) != 124
+failure_3
+#else
+success_3
+#endif
--- /dev/null
+
+
+
+success_1
+
+
+success_2
+
+
+
+
+
+
+success_3
+
+
--- /dev/null
+#define one 1
+#define two 2
+#define three 3
+#define five 5
+#if five < two
+failure_1
+#else
+success_1
+#endif
+#if three >= two
+success_2
+#else
+failure_2
+#endif
+#if two + three <= five
+success_3
+#else
+failure_3
+#endif
+#if five - two == three
+success_4
+#else
+failure_4
+#endif
+#if one > three
+failure_5
+#else
+success_5
+#endif
+#if one != five
+success_6
+#else
+failure_6
+#endif
--- /dev/null
+
+
+
+
+
+
+
+success_1
+
+
+success_2
+
+
+
+
+success_3
+
+
+
+
+success_4
+
+
+
+
+
+
+success_5
+
+
+success_6
+
+
+
+
--- /dev/null
+#define failure() success
+#define foo failure
+foo()
--- /dev/null
+
+
+success
+
--- /dev/null
+#define bar with,embedded,commas
+#define function(x) success
+#define foo function
+foo(bar)
--- /dev/null
+
+
+
+success
+
--- /dev/null
+#define zero() success
+zero()
+#define one(x) success
+one()
+#define two(x,y) success
+two(,)
--- /dev/null
+
+success
+
+success
+
+success
+
--- /dev/null
+#define paste(x,y) x ## y
+paste(a,b)
+paste(a,)
+paste(,b)
+paste(,)
--- /dev/null
+
+ab
+a
+b
+
+
--- /dev/null
+#define paste(x,y) x ## y
+paste(1,2)
+paste(1,000)
+paste(identifier,2)
--- /dev/null
+
+12
+1000
+identifier2
+
--- /dev/null
+#define double(a) a*2
+#define foo double(
+foo 5)
--- /dev/null
+#define foo(x) success
+#define bar foo
+#define baz bar
+#define joe baz
+joe (failure)
--- /dev/null
+
+
+
+
+success
+
--- /dev/null
+#define foo(a,b)
+#if 0
+foo(bar)
+foo(
+#endif
--- /dev/null
+
+
+
+
+
+
--- /dev/null
+/* this is a comment */
+// so is this
+// */
+f = g/**//h;
+/*//*/l();
+m = n//**/o
++ p;
+/* this
+comment spans
+multiple lines and
+contains *** stars
+and slashes / *** /
+and other stuff.
+****/
+more code here
+/* Test that /* nested
+ comments */
+are not treated like comments.
+/*/ this is a comment */
+/*/*/
--- /dev/null
+
+
+
+f = g /h;
+ l();
+m = n
++ p;
+
+more code here
+
+are not treated like comments.
+
+
+
--- /dev/null
+#version 130
+#define FOO
--- /dev/null
+#version 130
+
+
--- /dev/null
+#if defined(foo)
+failure_1
+#else
+success_1
+#endif
+#define foo
+#if defined ( foo )
+success_2
+#else
+failure_2
+#endif
+#undef foo
+#if defined (foo)
+failure_3
+#else
+success_3
+#endif
--- /dev/null
+
+
+
+success_1
+
+
+
+success_2
+
+
+
+
+
+
+
+success_3
+
+
--- /dev/null
+#define paste(x) success_ ## x
+paste(1) paste(2) paste(3)
--- /dev/null
+
+success_1 success_2 success_3
+
--- /dev/null
+#define x 3
+#define f(a) f(x * (a))
+#undef x
+#define x 2
+#define g f
+#define z z[0]
+#define h g(~
+#define m(a) a(w)
+#define w 0,1
+#define t(a) a
+#define p() int
+#define q(x) x
+#define r(x,y) x ## y
+f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+g(x +(3,4)-w) | h 5) & m
+ (f)^m(m);
+p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,)};
--- /dev/null
+
+
+
+
+
+
+
+
+
+
+
+
+
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+int i[] = { 1, 23, 4, 5, };
+
--- /dev/null
+#!/bin/sh
+
+for test in *.c; do
+ echo "Testing $test"
+ ../glcpp < $test > $test.out
+ diff -u $test.expected $test.out
+done
--- /dev/null
+/*
+ * 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 <talloc.h>
+
+void *
+xtalloc_named_const (const void *context, size_t size, const char *name)
+{
+ void *ret;
+
+ ret = talloc_named_const (context, size, name);
+ if (ret == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ return ret;
+}
+
+char *
+xtalloc_strdup (const void *t, const char *p)
+{
+ char *ret;
+
+ ret = talloc_strdup (t, p);
+ if (ret == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ return ret;
+}
+
+char *
+xtalloc_strndup (const void *t, const char *p, size_t n)
+{
+ char *ret;
+
+ ret = talloc_strndup (t, p, n);
+ if (ret == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ return ret;
+}
+
+char *
+xtalloc_asprintf (const void *t, const char *fmt, ...)
+{
+ va_list ap;
+ char *ret;
+
+ va_start(ap, fmt);
+
+ ret = talloc_vasprintf(t, fmt, ap);
+ if (ret == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ va_end(ap);
+ return ret;
+}
+
+void *
+_xtalloc_reference_loc (const void *context,
+ const void *ptr, const char *location)
+{
+ void *ret;
+
+ ret = _talloc_reference_loc (context, ptr, location);
+ if (ret == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ return ret;
+}
--- /dev/null
+%{
+/*
+ * 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 <ctype.h>
+#include "ast.h"
+#include "glsl_parser_extras.h"
+#include "glsl_parser.h"
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->source = 0; \
+ yylloc->first_column = yycolumn + 1; \
+ yylloc->first_line = yylineno + 1; \
+ yycolumn += yyleng; \
+ } while(0);
+
+%}
+
+%option bison-bridge bison-locations reentrant noyywrap
+%option nounput noyy_top_state
+%option never-interactive
+%option prefix="_mesa_glsl_"
+%option extra-type="struct _mesa_glsl_parse_state *"
+
+%x PP
+
+DEC_INT [1-9][0-9]*
+HEX_INT 0[xX][0-9a-fA-F]+
+OCT_INT 0[0-7]*
+INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
+SPC [ \t]*
+SPCP [ \t]+
+HASH ^{SPC}#{SPC}
+%%
+
+[ \r\t]+ ;
+
+ /* Preprocessor tokens. */
+^[ \t]*#[ \t]*$ ;
+^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
+^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
+{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
+ /* Eat characters until the first digit is
+ * encountered
+ */
+ char *ptr = yytext;
+ while (!isdigit(*ptr))
+ ptr++;
+
+ /* Subtract one from the line number because
+ * yylineno is zero-based instead of
+ * one-based.
+ */
+ yylineno = strtol(ptr, &ptr, 0) - 1;
+ yylloc->source = strtol(ptr, NULL, 0);
+ }
+{HASH}line{SPCP}{INT}{SPC}$ {
+ /* Eat characters until the first digit is
+ * encountered
+ */
+ char *ptr = yytext;
+ while (!isdigit(*ptr))
+ ptr++;
+
+ /* Subtract one from the line number because
+ * yylineno is zero-based instead of
+ * one-based.
+ */
+ yylineno = strtol(ptr, &ptr, 0) - 1;
+ }
+^[ \t]*#[ \t]*pragma { BEGIN PP; return PRAGMA; }
+<PP>\/\/[^\n]* { }
+<PP>[ \t\r]* { }
+<PP>: return COLON;
+<PP>[_a-zA-Z][_a-zA-Z0-9]* {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+<PP>[1-9][0-9]* {
+ yylval->n = strtol(yytext, NULL, 10);
+ return INTCONSTANT;
+ }
+<PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
+
+\n { yylineno++; yycolumn = 0; }
+
+attribute return ATTRIBUTE;
+const return CONST;
+bool return BOOL;
+float return FLOAT;
+int return INT;
+
+break return BREAK;
+continue return CONTINUE;
+do return DO;
+while return WHILE;
+else return ELSE;
+for return FOR;
+if return IF;
+discard return DISCARD;
+return return RETURN;
+
+bvec2 return BVEC2;
+bvec3 return BVEC3;
+bvec4 return BVEC4;
+ivec2 return IVEC2;
+ivec3 return IVEC3;
+ivec4 return IVEC4;
+vec2 return VEC2;
+vec3 return VEC3;
+vec4 return VEC4;
+mat2 return MAT2;
+mat3 return MAT3;
+mat4 return MAT4;
+mat2x2 return MAT2X2;
+mat2x3 return MAT2X3;
+mat2x4 return MAT2X4;
+mat3x2 return MAT3X2;
+mat3x3 return MAT3X3;
+mat3x4 return MAT3X4;
+mat4x2 return MAT4X2;
+mat4x3 return MAT4X3;
+mat4x4 return MAT4X4;
+
+in return IN;
+out return OUT;
+inout return INOUT;
+uniform return UNIFORM;
+varying return VARYING;
+centroid {
+ if (yyextra->language_version >= 120) {
+ return CENTROID;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+invariant {
+ if (yyextra->language_version >= 120) {
+ return INVARIANT;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+
+flat {
+ if (yyextra->language_version >= 130) {
+ return FLAT;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+smooth {
+ if (yyextra->language_version >= 130) {
+ return SMOOTH;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+noperspective {
+ if (yyextra->language_version >= 130) {
+ return NOPERSPECTIVE;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+
+sampler1D return SAMPLER1D;
+sampler2D return SAMPLER2D;
+sampler3D return SAMPLER3D;
+samplerCube return SAMPLERCUBE;
+sampler1DShadow return SAMPLER1DSHADOW;
+sampler2DShadow return SAMPLER2DSHADOW;
+
+struct return STRUCT;
+void return VOID;
+
+\+\+ return INC_OP;
+-- return DEC_OP;
+\<= return LE_OP;
+>= return GE_OP;
+== return EQ_OP;
+!= return NE_OP;
+&& return AND_OP;
+\|\| return OR_OP;
+"^^" return XOR_OP;
+
+\*= return MUL_ASSIGN;
+\/= return DIV_ASSIGN;
+\+= return ADD_ASSIGN;
+\%= return MOD_ASSIGN;
+\<\<= return LEFT_ASSIGN;
+>>= return RIGHT_ASSIGN;
+&= return AND_ASSIGN;
+^= return XOR_ASSIGN;
+\|= return OR_ASSIGN;
+-= return SUB_ASSIGN;
+
+[1-9][0-9]* {
+ yylval->n = strtol(yytext, NULL, 10);
+ return INTCONSTANT;
+ }
+0[xX][0-9a-fA-F]+ {
+ yylval->n = strtol(yytext + 2, NULL, 16);
+ return INTCONSTANT;
+ }
+0[0-7]* {
+ yylval->n = strtol(yytext + 2, NULL, 8);
+ return INTCONSTANT;
+ }
+
+[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+[eE][+-]?[0-9]+[fF]? {
+ yylval->real = strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+
+true {
+ yylval->n = 1;
+ return BOOLCONSTANT;
+ }
+false {
+ yylval->n = 0;
+ return BOOLCONSTANT;
+ }
+
+
+ /* Reserved words in GLSL 1.10. */
+asm return ASM;
+class return CLASS;
+union return UNION;
+enum return ENUM;
+typedef return TYPEDEF;
+template return TEMPLATE;
+this return THIS;
+packed return PACKED;
+goto return GOTO;
+switch return SWITCH;
+default return DEFAULT;
+inline return INLINE;
+noinline return NOINLINE;
+volatile return VOLATILE;
+public return PUBLIC;
+static return STATIC;
+extern return EXTERN;
+external return EXTERNAL;
+interface return INTERFACE;
+long return LONG;
+short return SHORT;
+double return DOUBLE;
+half return HALF;
+fixed return FIXED;
+unsigned return UNSIGNED;
+input return INPUT;
+output return OUTPUT;
+hvec2 return HVEC2;
+hvec3 return HVEC3;
+hvec4 return HVEC4;
+dvec2 return DVEC2;
+dvec3 return DVEC3;
+dvec4 return DVEC4;
+fvec2 return FVEC2;
+fvec3 return FVEC3;
+fvec4 return FVEC4;
+sampler2DRect return SAMPLER2DRECT;
+sampler3DRect return SAMPLER3DRECT;
+sampler2DRectShadow return SAMPLER2DRECTSHADOW;
+sizeof return SIZEOF;
+cast return CAST;
+namespace return NAMESPACE;
+using return USING;
+
+ /* Additional reserved words in GLSL 1.20. */
+lowp return LOWP;
+mediump return MEDIUMP;
+highp return HIGHP;
+precision return PRECISION;
+
+[_a-zA-Z][_a-zA-Z0-9]* {
+ struct _mesa_glsl_parse_state *state = yyextra;
+ void *ctx = talloc_parent(state);
+ yylval->identifier = talloc_strdup(ctx, yytext);
+ return IDENTIFIER;
+ }
+
+. { return yytext[0]; }
+
+%%
+
+void
+_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
+{
+ yylex_init_extra(state, & state->scanner);
+ yy_scan_string(string, state->scanner);
+}
+
+void
+_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
+{
+ yylex_destroy(state->scanner);
+}
--- /dev/null
+%{
+/*
+ * 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
+%locations
+%error-verbose
+
+%lex-param {void *scanner}
+%parse-param {struct _mesa_glsl_parse_state *state}
+%name-prefix "_mesa_glsl_"
+
+%union {
+ int n;
+ float real;
+ char *identifier;
+
+ union {
+ struct ast_type_qualifier q;
+ unsigned i;
+ } type_qualifier;
+
+ struct ast_node *node;
+ struct ast_type_specifier *type_specifier;
+ struct ast_fully_specified_type *fully_specified_type;
+ struct ast_function *function;
+ struct ast_parameter_declarator *parameter_declarator;
+ struct ast_function_definition *function_definition;
+ struct ast_compound_statement *compound_statement;
+ struct ast_expression *expression;
+ struct ast_declarator_list *declarator_list;
+ struct ast_struct_specifier *struct_specifier;
+ struct ast_declaration *declaration;
+
+ struct {
+ struct ast_node *cond;
+ struct ast_expression *rest;
+ } for_rest_statement;
+}
+
+%token ATTRIBUTE CONST BOOL FLOAT INT UINT
+%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 MAT2 MAT3 MAT4 CENTROID IN OUT INOUT 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 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 PRECISION
+
+%token VERSION EXTENSION LINE PRAGMA COLON EOL INTERFACE OUTPUT
+
+ /* Reserved words that are not actually used in the grammar.
+ */
+%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED GOTO
+%token INLINE NOINLINE VOLATILE PUBLIC STATIC EXTERN EXTERNAL
+%token LONG SHORT DOUBLE HALF FIXED UNSIGNED INPUT OUPTUT
+%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
+%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW
+%token SIZEOF CAST NAMESPACE USING
+
+%type <identifier> variable_identifier
+%type <node> statement
+%type <node> statement_list
+%type <node> simple_statement
+%type <node> statement_matched
+%type <node> statement_unmatched
+%type <n> precision_qualifier
+%type <type_qualifier> type_qualifier
+%type <type_qualifier> storage_qualifier
+%type <type_qualifier> interpolation_qualifier
+%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_matched
+%type <node> selection_statement_unmatched
+%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 */
+ {
+ state->language_version = 110;
+ }
+ | VERSION INTCONSTANT EOL
+ {
+ switch ($2) {
+ case 110:
+ case 120:
+ case 130:
+ /* FINISHME: Check against implementation support versions. */
+ state->language_version = $2;
+ break;
+ default:
+ _mesa_glsl_error(& @2, state, "Shading language version"
+ "%u is not supported\n", $2);
+ break;
+ }
+ }
+ ;
+
+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 = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.identifier = $1;
+ }
+ | INTCONSTANT
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.int_constant = $1;
+ }
+ | UINTCONSTANT
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.uint_constant = $1;
+ }
+ | FLOATCONSTANT
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.float_constant = $1;
+ }
+ | BOOLCONSTANT
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL);
+ $$->set_location(yylloc);
+ }
+ | function_call
+ {
+ /* Function call parameters used to be stored as a circular list in
+ * subexpressions[1]. They are now stored as a regular list in
+ * expressions. This assertion validates that the old code was
+ * correctly converted. It can eventually be removed.
+ */
+ assert($1->subexpressions[1] == NULL);
+ $$ = $1;
+ }
+ | postfix_expression '.' IDENTIFIER
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.identifier = $3;
+ }
+ | postfix_expression INC_OP
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | postfix_expression DEC_OP
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(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
+ | 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 = talloc_parent(state);
+ $$ = new(ctx) ast_function_expression($1);
+ $$->set_location(yylloc);
+ }
+ | IDENTIFIER
+ {
+ void *ctx = talloc_parent(state);
+ ast_expression *callee = new(ctx) ast_expression($1);
+ $$ = new(ctx) ast_function_expression(callee);
+ $$->set_location(yylloc);
+ }
+ | FIELD_SELECTION
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | DEC_OP unary_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | unary_operator unary_expression
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | multiplicative_expression '/' unary_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_div, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | multiplicative_expression '%' unary_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+additive_expression:
+ multiplicative_expression
+ | additive_expression '+' multiplicative_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_add, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | additive_expression '-' multiplicative_expression
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | shift_expression RIGHT_OP additive_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+relational_expression:
+ shift_expression
+ | relational_expression '<' shift_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_less, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | relational_expression '>' shift_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | relational_expression LE_OP shift_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | relational_expression GE_OP shift_expression
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | equality_expression NE_OP relational_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+and_expression:
+ equality_expression
+ | and_expression '&' equality_expression
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+exclusive_or_expression:
+ and_expression
+ | exclusive_or_expression '^' and_expression
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_function();
+ $$->set_location(yylloc);
+ $$->return_type = $1;
+ $$->identifier = $2;
+ }
+ ;
+
+parameter_declarator:
+ type_specifier IDENTIFIER
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(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.i |= $2.i;
+
+ $$ = $3;
+ $$->type->qualifier = $1.q;
+ }
+ | parameter_qualifier parameter_declarator
+ {
+ $$ = $2;
+ $$->type->qualifier = $1.q;
+ }
+ | parameter_type_qualifier parameter_qualifier parameter_type_specifier
+ {
+ void *ctx = talloc_parent(state);
+ $1.i |= $2.i;
+
+ $$ = new(ctx) ast_parameter_declarator();
+ $$->set_location(yylloc);
+ $$->type = new(ctx) ast_fully_specified_type();
+ $$->type->qualifier = $1.q;
+ $$->type->specifier = $3;
+ }
+ | parameter_qualifier parameter_type_specifier
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_parameter_declarator();
+ $$->set_location(yylloc);
+ $$->type = new(ctx) ast_fully_specified_type();
+ $$->type->qualifier = $1.q;
+ $$->type->specifier = $2;
+ }
+ ;
+
+parameter_qualifier:
+ /* empty */ { $$.i = 0; }
+ | IN { $$.i = 0; $$.q.in = 1; }
+ | OUT { $$.i = 0; $$.q.out = 1; }
+ | INOUT { $$.i = 0; $$.q.in = 1; $$.q.out = 1; }
+ ;
+
+parameter_type_specifier:
+ type_specifier
+ ;
+
+init_declarator_list:
+ single_declaration
+ | init_declarator_list ',' IDENTIFIER
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_fully_specified_type();
+ $$->set_location(yylloc);
+ $$->specifier = $1;
+ }
+ | type_qualifier type_specifier
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_fully_specified_type();
+ $$->set_location(yylloc);
+ $$->qualifier = $1.q;
+ $$->specifier = $2;
+ }
+ ;
+
+interpolation_qualifier:
+ SMOOTH { $$.i = 0; $$.q.smooth = 1; }
+ | FLAT { $$.i = 0; $$.q.flat = 1; }
+ | NOPERSPECTIVE { $$.i = 0; $$.q.noperspective = 1; }
+ ;
+
+parameter_type_qualifier:
+ CONST { $$.i = 0; $$.q.constant = 1; }
+ ;
+
+type_qualifier:
+ storage_qualifier
+ | interpolation_qualifier type_qualifier
+ {
+ $$.i = $1.i | $2.i;
+ }
+ | INVARIANT type_qualifier
+ {
+ $$ = $2;
+ $$.q.invariant = 1;
+ }
+ ;
+
+storage_qualifier:
+ CONST { $$.i = 0; $$.q.constant = 1; }
+ | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; }
+ | VARYING { $$.i = 0; $$.q.varying = 1; }
+ | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; }
+ | IN { $$.i = 0; $$.q.in = 1; }
+ | OUT { $$.i = 0; $$.q.out = 1; }
+ | CENTROID IN { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; }
+ | CENTROID OUT { $$.i = 0; $$.q.centroid = 1; $$.q.out = 1; }
+ | UNIFORM { $$.i = 0; $$.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 = talloc_parent(state);
+ $$ = new(ctx) ast_type_specifier($1);
+ $$->set_location(yylloc);
+ }
+ | struct_specifier
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_type_specifier($1);
+ $$->set_location(yylloc);
+ }
+ | IDENTIFIER
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_type_specifier($1);
+ $$->set_location(yylloc);
+ }
+ ;
+
+basic_type_specifier_nonarray:
+ VOID { $$ = ast_void; }
+ | FLOAT { $$ = ast_float; }
+ | INT { $$ = ast_int; }
+ | UINT { $$ = ast_uint; }
+ | BOOL { $$ = 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; }
+ | MAT2 { $$ = ast_mat2; }
+ | MAT3 { $$ = ast_mat3; }
+ | MAT4 { $$ = ast_mat4; }
+ | 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->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precission qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ $$ = ast_precision_high;
+ }
+ | MEDIUMP {
+ if (state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precission qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ $$ = ast_precision_medium;
+ }
+ | LOWP {
+ if (state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precission qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ $$ = ast_precision_low;
+ }
+ ;
+
+struct_specifier:
+ STRUCT IDENTIFIER '{' struct_declaration_list '}'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_struct_specifier($2, $4);
+ $$->set_location(yylloc);
+ }
+ | STRUCT '{' struct_declaration_list '}'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_struct_specifier(NULL, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+struct_declaration_list:
+ struct_declaration
+ {
+ $$ = (struct ast_node *) $1;
+ $1->link.self_link();
+ }
+ | struct_declaration_list struct_declaration
+ {
+ $$ = (struct ast_node *) $1;
+ $$->link.insert_before(& $2->link);
+ }
+ ;
+
+struct_declaration:
+ type_specifier struct_declarator_list ';'
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_declaration($1, false, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | IDENTIFIER '[' constant_expression ']'
+ {
+ void *ctx = talloc_parent(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:
+ statement_matched
+ | statement_unmatched
+ ;
+
+statement_matched:
+ compound_statement { $$ = (struct ast_node *) $1; }
+ | simple_statement
+ ;
+
+statement_unmatched:
+ selection_statement_unmatched
+ ;
+
+simple_statement:
+ declaration_statement
+ | expression_statement
+ | selection_statement_matched
+ | switch_statement { $$ = NULL; }
+ | case_label { $$ = NULL; }
+ | iteration_statement
+ | jump_statement
+ ;
+
+compound_statement:
+ '{' '}'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_compound_statement(true, NULL);
+ $$->set_location(yylloc);
+ }
+ | '{' statement_list '}'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_compound_statement(true, $2);
+ $$->set_location(yylloc);
+ }
+ ;
+
+statement_no_new_scope:
+ compound_statement_no_new_scope { $$ = (struct ast_node *) $1; }
+ | simple_statement
+ ;
+
+compound_statement_no_new_scope:
+ '{' '}'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_compound_statement(false, NULL);
+ $$->set_location(yylloc);
+ }
+ | '{' statement_list '}'
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_expression_statement(NULL);
+ $$->set_location(yylloc);
+ }
+ | expression ';'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_expression_statement($1);
+ $$->set_location(yylloc);
+ }
+ ;
+
+selection_statement_matched:
+ IF '(' expression ')' statement_matched ELSE statement_matched
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_selection_statement($3, $5, $7);
+ $$->set_location(yylloc);
+ }
+ ;
+
+selection_statement_unmatched:
+ IF '(' expression ')' statement_matched
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_selection_statement($3, $5, NULL);
+ $$->set_location(yylloc);
+ }
+ | IF '(' expression ')' statement_unmatched
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_selection_statement($3, $5, NULL);
+ $$->set_location(yylloc);
+ }
+ | IF '(' expression ')' statement_matched ELSE statement_unmatched
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_selection_statement($3, $5, $7);
+ $$->set_location(yylloc);
+ }
+ ;
+
+condition:
+ expression
+ {
+ $$ = (struct ast_node *) $1;
+ }
+ | fully_specified_type IDENTIFIER '=' initializer
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while,
+ NULL, $3, NULL, $5);
+ $$->set_location(yylloc);
+ }
+ | DO statement WHILE '(' expression ')' ';'
+ {
+ void *ctx = talloc_parent(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 = talloc_parent(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 = talloc_parent(state);
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL);
+ $$->set_location(yylloc);
+ }
+ | BREAK ';'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL);
+ $$->set_location(yylloc);
+ }
+ | RETURN ';'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL);
+ $$->set_location(yylloc);
+ }
+ | RETURN expression ';'
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2);
+ $$->set_location(yylloc);
+ }
+ | DISCARD ';' // Fragment shader only.
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL);
+ $$->set_location(yylloc);
+ }
+ ;
+
+external_declaration:
+ function_definition { $$ = $1; }
+ | declaration { $$ = $1; }
+ ;
+
+function_definition:
+ function_prototype compound_statement_no_new_scope
+ {
+ void *ctx = talloc_parent(state);
+ $$ = new(ctx) ast_function_definition();
+ $$->set_location(yylloc);
+ $$->prototype = $1;
+ $$->body = $2;
+ }
+ ;
--- /dev/null
+/*
+ * 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 "ast.h"
+#include "glsl_parser_extras.h"
+#include "glsl_parser.h"
+
+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";
+ case ir_shader: break;
+ }
+
+ assert(!"Should not get here.");
+}
+
+
+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_texture_rectangle") == 0) {
+ state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
+ state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
+ } 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->constant)
+ printf("const ");
+
+ if (q->invariant)
+ printf("invariant ");
+
+ if (q->attribute)
+ printf("attribute ");
+
+ if (q->varying)
+ printf("varying ");
+
+ if (q->in && q->out)
+ printf("inout ");
+ else {
+ if (q->in)
+ printf("in ");
+
+ if (q->out)
+ printf("out ");
+ }
+
+ if (q->centroid)
+ printf("centroid ");
+ if (q->uniform)
+ printf("uniform ");
+ if (q->smooth)
+ printf("smooth ");
+ if (q->flat)
+ printf("flat ");
+ if (q->noperspective)
+ printf("noperspective ");
+}
+
+
+void
+ast_node::print(void) const
+{
+ printf("unhandled node ");
+}
+
+
+ast_node::ast_node(void)
+{
+ /* empty */
+}
+
+
+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;
+}
+
+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)
+{
+ name = identifier;
+ this->declarations.push_degenerate_list_at_head(&declarator_list->link);
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef GLSL_PARSER_EXTRAS_H
+#define GLSL_PARSER_EXTRAS_H
+
+#include <cstdlib>
+#include "glsl_symbol_table.h"
+
+enum _mesa_glsl_parser_targets {
+ vertex_shader,
+ geometry_shader,
+ fragment_shader,
+ ir_shader
+};
+
+struct _mesa_glsl_parse_state {
+ void *scanner;
+ exec_list translation_unit;
+ glsl_symbol_table *symbols;
+
+ unsigned language_version;
+ enum _mesa_glsl_parser_targets target;
+
+ /**
+ * During AST to IR conversion, pointer to current IR function
+ *
+ * Will be \c NULL whenever the AST to IR conversion is not inside a
+ * function definition.
+ */
+ class ir_function_signature *current_function;
+
+ /** Was there an error during compilation? */
+ bool error;
+
+ /** Index of last generated anonymous temporary. */
+ unsigned temp_index;
+
+ /** Loop or switch statement containing the current instructions. */
+ class ir_instruction *loop_or_switch_nesting;
+
+ /** List of structures defined in user code. */
+ const glsl_type **user_structures;
+ unsigned num_user_structures;
+
+ char *info_log;
+
+ /**
+ * \name Enable bits for GLSL extensions
+ */
+ /*@{*/
+ unsigned ARB_draw_buffers_enable:1;
+ unsigned ARB_draw_buffers_warn:1;
+ unsigned ARB_texture_rectangle_enable:1;
+ unsigned ARB_texture_rectangle_warn:1;
+ unsigned EXT_texture_array_enable:1;
+ unsigned EXT_texture_array_warn:1;
+ /*@}*/
+};
+
+typedef struct YYLTYPE {
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ unsigned source;
+} YYLTYPE;
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+
+extern void _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
+ const char *fmt, ...);
+
+/**
+ * Emit a warning to the shader log
+ *
+ * \sa _mesa_glsl_error
+ */
+extern void _mesa_glsl_warning(const YYLTYPE *locp,
+ _mesa_glsl_parse_state *state,
+ const char *fmt, ...);
+
+extern "C" {
+extern int preprocess(void *ctx, const char **shader, char **info_log);
+}
+
+extern void _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state,
+ const char *string);
+
+extern void _mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state);
+
+union YYSTYPE;
+extern int _mesa_glsl_lex(union YYSTYPE *yylval, YYLTYPE *yylloc,
+ void *scanner);
+
+extern int _mesa_glsl_parse(struct _mesa_glsl_parse_state *);
+
+/**
+ * Process elements of the #extension directive
+ *
+ * \return
+ * If \c name and \c behavior are valid, \c true is returned. Otherwise
+ * \c false is returned.
+ */
+extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
+ const char *behavior,
+ YYLTYPE *behavior_locp,
+ _mesa_glsl_parse_state *state);
+
+/**
+ * Get the textual name of the specified shader target
+ */
+extern const char *
+_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target);
+
+void do_ir_to_mesa(exec_list *instructions);
+
+#endif /* GLSL_PARSER_EXTRAS_H */
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef GLSL_SYMBOL_TABLE
+#define GLSL_SYMBOL_TABLE
+
+#include <new>
+
+#include "symbol_table.h"
+#include "ir.h"
+#include "glsl_types.h"
+
+/**
+ * Facade class for _mesa_symbol_table
+ *
+ * Wraps the existing \c _mesa_symbol_table data structure to enforce some
+ * type safe and some symbol table invariants.
+ */
+class glsl_symbol_table {
+private:
+ enum glsl_symbol_name_space {
+ glsl_variable_name_space = 0,
+ glsl_type_name_space = 1,
+ glsl_function_name_space = 2
+ };
+
+ static int
+ _glsl_symbol_table_destructor (glsl_symbol_table *table)
+ {
+ table->~glsl_symbol_table();
+
+ return 0;
+ }
+
+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 *table;
+
+ table = talloc_size(ctx, size);
+ assert(table != NULL);
+
+ talloc_set_destructor(table, (int (*)(void*)) _glsl_symbol_table_destructor);
+
+ return table;
+ }
+
+ /* If the user *does* call delete, that's OK, we will just
+ * talloc_free in that case. Here, C++ will have already called the
+ * destructor so tell talloc not to do that again. */
+ static void operator delete(void *table)
+ {
+ talloc_set_destructor(table, NULL);
+ talloc_free(table);
+ }
+
+ glsl_symbol_table()
+ {
+ table = _mesa_symbol_table_ctor();
+ }
+
+ ~glsl_symbol_table()
+ {
+ _mesa_symbol_table_dtor(table);
+ }
+
+ void push_scope()
+ {
+ _mesa_symbol_table_push_scope(table);
+ }
+
+ void pop_scope()
+ {
+ _mesa_symbol_table_pop_scope(table);
+ }
+
+ /**
+ * Determine whether a name was declared at the current scope
+ */
+ bool name_declared_this_scope(const char *name)
+ {
+ return _mesa_symbol_table_symbol_scope(table, -1, name) == 0;
+ }
+
+ /**
+ * \name Methods to add symbols to the table
+ *
+ * There is some temptation to rename all these functions to \c add_symbol
+ * or similar. However, this breaks symmetry with the getter functions and
+ * reduces the clarity of the intention of code that uses these methods.
+ */
+ /*@{*/
+ bool add_variable(const char *name, ir_variable *v)
+ {
+ return _mesa_symbol_table_add_symbol(table, glsl_variable_name_space,
+ name, v) == 0;
+ }
+
+ bool add_type(const char *name, const glsl_type *t)
+ {
+ return _mesa_symbol_table_add_symbol(table, glsl_type_name_space,
+ name, (void *) t) == 0;
+ }
+
+ bool add_function(const char *name, ir_function *f)
+ {
+ return _mesa_symbol_table_add_symbol(table, glsl_function_name_space,
+ name, f) == 0;
+ }
+ /*@}*/
+
+ /**
+ * \name Methods to get symbols from the table
+ */
+ /*@{*/
+ ir_variable *get_variable(const char *name)
+ {
+ return (ir_variable *)
+ _mesa_symbol_table_find_symbol(table, glsl_variable_name_space, name);
+ }
+
+ glsl_type *get_type(const char *name)
+ {
+ return (glsl_type *)
+ _mesa_symbol_table_find_symbol(table, glsl_type_name_space, name);
+ }
+
+ ir_function *get_function(const char *name)
+ {
+ return (ir_function *)
+ _mesa_symbol_table_find_symbol(table, glsl_function_name_space, name);
+ }
+ /*@}*/
+
+private:
+ struct _mesa_symbol_table *table;
+};
+
+#endif /* GLSL_SYMBOL_TABLE */
--- /dev/null
+/*
+ * 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.
+ */
+
+#include <cstdio>
+#include <stdlib.h>
+#include "glsl_symbol_table.h"
+#include "glsl_parser_extras.h"
+#include "glsl_types.h"
+#include "builtin_types.h"
+#include "hash_table.h"
+
+
+hash_table *glsl_type::array_types = NULL;
+
+static void
+add_types_to_symbol_table(glsl_symbol_table *symtab,
+ const struct glsl_type *types,
+ unsigned num_types, bool warn)
+{
+ (void) warn;
+
+ for (unsigned i = 0; i < num_types; i++) {
+ symtab->add_type(types[i].name, & types[i]);
+ }
+}
+
+
+static void
+generate_110_types(glsl_symbol_table *symtab)
+{
+ add_types_to_symbol_table(symtab, builtin_core_types,
+ Elements(builtin_core_types),
+ false);
+ add_types_to_symbol_table(symtab, builtin_structure_types,
+ Elements(builtin_structure_types),
+ false);
+ add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
+ Elements(builtin_110_deprecated_structure_types),
+ false);
+ add_types_to_symbol_table(symtab, & void_type, 1, false);
+}
+
+
+static void
+generate_120_types(glsl_symbol_table *symtab)
+{
+ generate_110_types(symtab);
+
+ add_types_to_symbol_table(symtab, builtin_120_types,
+ Elements(builtin_120_types), false);
+}
+
+
+static void
+generate_130_types(glsl_symbol_table *symtab)
+{
+ generate_120_types(symtab);
+
+ add_types_to_symbol_table(symtab, builtin_130_types,
+ Elements(builtin_130_types), false);
+}
+
+
+static void
+generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab, bool warn)
+{
+ add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
+ Elements(builtin_ARB_texture_rectangle_types),
+ warn);
+}
+
+
+static void
+generate_EXT_texture_array_types(glsl_symbol_table *symtab, bool warn)
+{
+ add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
+ Elements(builtin_EXT_texture_array_types),
+ warn);
+}
+
+
+void
+_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
+{
+ switch (state->language_version) {
+ case 110:
+ generate_110_types(state->symbols);
+ break;
+ case 120:
+ generate_120_types(state->symbols);
+ break;
+ case 130:
+ generate_130_types(state->symbols);
+ break;
+ default:
+ /* error */
+ break;
+ }
+
+ if (state->ARB_texture_rectangle_enable) {
+ generate_ARB_texture_rectangle_types(state->symbols,
+ state->ARB_texture_rectangle_warn);
+ }
+
+ if (state->EXT_texture_array_enable && state->language_version < 130) {
+ // These are already included in 130; don't create twice.
+ generate_EXT_texture_array_types(state->symbols,
+ state->EXT_texture_array_warn);
+ }
+}
+
+
+const glsl_type *glsl_type::get_base_type() const
+{
+ switch (base_type) {
+ case GLSL_TYPE_UINT:
+ return uint_type;
+ case GLSL_TYPE_INT:
+ return int_type;
+ case GLSL_TYPE_FLOAT:
+ return float_type;
+ case GLSL_TYPE_BOOL:
+ return bool_type;
+ default:
+ return error_type;
+ }
+}
+
+
+ir_function *
+glsl_type::generate_constructor(glsl_symbol_table *symtab) const
+{
+ void *ctx = symtab;
+
+ /* Generate the function name and add it to the symbol table.
+ */
+ ir_function *const f = new(ctx) ir_function(name);
+
+ bool added = symtab->add_function(name, f);
+ assert(added);
+
+ ir_function_signature *const sig = new(ctx) ir_function_signature(this);
+ f->add_signature(sig);
+
+ ir_variable **declarations =
+ (ir_variable **) malloc(sizeof(ir_variable *) * this->length);
+ for (unsigned i = 0; i < length; i++) {
+ char *const param_name = (char *) malloc(10);
+
+ snprintf(param_name, 10, "p%08X", i);
+
+ ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY)
+ ? new(ctx) ir_variable(fields.array, param_name)
+ : new(ctx) ir_variable(fields.structure[i].type, param_name);
+
+ var->mode = ir_var_in;
+ declarations[i] = var;
+ sig->parameters.push_tail(var);
+ }
+
+ /* Generate the body of the constructor. The body assigns each of the
+ * parameters to a portion of a local variable called __retval that has
+ * the same type as the constructor. After initializing __retval,
+ * __retval is returned.
+ */
+ ir_variable *retval = new(ctx) ir_variable(this, "__retval");
+ sig->body.push_tail(retval);
+
+ for (unsigned i = 0; i < length; i++) {
+ ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY)
+ ? (ir_dereference *) new(ctx) ir_dereference_array(retval,
+ new(ctx) ir_constant(i))
+ : (ir_dereference *) new(ctx) ir_dereference_record(retval,
+ fields.structure[i].name);
+
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
+ ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL);
+
+ sig->body.push_tail(assign);
+ }
+
+ free(declarations);
+
+ ir_dereference *const retref = new(ctx) ir_dereference_variable(retval);
+ ir_instruction *const inst = new(ctx) ir_return(retref);
+ sig->body.push_tail(inst);
+
+ return f;
+}
+
+
+/**
+ * Generate the function intro for a constructor
+ *
+ * \param type Data type to be constructed
+ * \param count Number of parameters to this concrete constructor. Most
+ * types have at least two constructors. One will take a
+ * single scalar parameter and the other will take "N"
+ * scalar parameters.
+ * \param parameters Storage for the list of parameters. These are
+ * typically stored in an \c ir_function_signature.
+ * \param declarations Pointers to the variable declarations for the function
+ * parameters. These are used later to avoid having to use
+ * the symbol table.
+ */
+static ir_function_signature *
+generate_constructor_intro(void *ctx,
+ const glsl_type *type, unsigned parameter_count,
+ ir_variable **declarations)
+{
+ /* Names of parameters used in vector and matrix constructors
+ */
+ static const char *const names[] = {
+ "a", "b", "c", "d", "e", "f", "g", "h",
+ "i", "j", "k", "l", "m", "n", "o", "p",
+ };
+
+ assert(parameter_count <= Elements(names));
+
+ const glsl_type *const parameter_type = type->get_base_type();
+
+ ir_function_signature *const signature = new(ctx) ir_function_signature(type);
+
+ for (unsigned i = 0; i < parameter_count; i++) {
+ ir_variable *var = new(ctx) ir_variable(parameter_type, names[i]);
+
+ var->mode = ir_var_in;
+ signature->parameters.push_tail(var);
+
+ declarations[i] = var;
+ }
+
+ ir_variable *retval = new(ctx) ir_variable(type, "__retval");
+ signature->body.push_tail(retval);
+
+ declarations[16] = retval;
+ return signature;
+}
+
+
+/**
+ * Generate the body of a vector constructor that takes a single scalar
+ */
+static void
+generate_vec_body_from_scalar(void *ctx,
+ exec_list *instructions,
+ ir_variable **declarations)
+{
+ ir_instruction *inst;
+
+ /* Generate a single assignment of the parameter to __retval.x and return
+ * __retval.xxxx for however many vector components there are.
+ */
+ ir_dereference *const lhs_ref =
+ new(ctx) ir_dereference_variable(declarations[16]);
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
+
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
+
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
+ instructions->push_tail(inst);
+
+ ir_dereference *const retref = new(ctx) ir_dereference_variable(declarations[16]);
+
+ ir_swizzle *retval = new(ctx) ir_swizzle(retref, 0, 0, 0, 0,
+ declarations[16]->type->vector_elements);
+
+ inst = new(ctx) ir_return(retval);
+ instructions->push_tail(inst);
+}
+
+
+/**
+ * Generate the body of a vector constructor that takes multiple scalars
+ */
+static void
+generate_vec_body_from_N_scalars(void *ctx,
+ exec_list *instructions,
+ ir_variable **declarations)
+{
+ ir_instruction *inst;
+ const glsl_type *const vec_type = declarations[16]->type;
+
+ /* Generate an assignment of each parameter to a single component of
+ * __retval.x and return __retval.
+ */
+ for (unsigned i = 0; i < vec_type->vector_elements; i++) {
+ ir_dereference *const lhs_ref =
+ new(ctx) ir_dereference_variable(declarations[16]);
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
+
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
+
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
+ instructions->push_tail(inst);
+ }
+
+ ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
+
+ inst = new(ctx) ir_return(retval);
+ instructions->push_tail(inst);
+}
+
+
+/**
+ * Generate the body of a matrix constructor that takes a single scalar
+ */
+static void
+generate_mat_body_from_scalar(void *ctx,
+ exec_list *instructions,
+ ir_variable **declarations)
+{
+ ir_instruction *inst;
+
+ /* Generate an assignment of the parameter to the X component of a
+ * temporary vector. Set the remaining fields of the vector to 0. The
+ * size of the vector is equal to the number of rows of the matrix.
+ *
+ * Set each column of the matrix to a successive "rotation" of the
+ * temporary vector. This fills the matrix with 0s, but writes the single
+ * scalar along the matrix's diagonal.
+ *
+ * For a mat4x3, this is equivalent to:
+ *
+ * vec3 tmp;
+ * mat4x3 __retval;
+ * tmp.x = a;
+ * tmp.y = 0.0;
+ * tmp.z = 0.0;
+ * __retval[0] = tmp.xyy;
+ * __retval[1] = tmp.yxy;
+ * __retval[2] = tmp.yyx;
+ * __retval[3] = tmp.yyy;
+ */
+ const glsl_type *const column_type = declarations[16]->type->column_type();
+ const glsl_type *const row_type = declarations[16]->type->row_type();
+
+ ir_variable *const column = new(ctx) ir_variable(column_type, "v");
+
+ instructions->push_tail(column);
+
+ ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
+
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
+
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
+ instructions->push_tail(inst);
+
+ for (unsigned i = 1; i < column_type->vector_elements; i++) {
+ ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
+ ir_constant *const zero = new(ctx) ir_constant(0.0f);
+
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
+
+ inst = new(ctx) ir_assignment(lhs, zero, NULL);
+ instructions->push_tail(inst);
+ }
+
+
+ for (unsigned i = 0; i < row_type->vector_elements; i++) {
+ static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 };
+ ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(column);
+
+ /* This will be .xyyy when i=0, .yxyy when i=1, etc.
+ */
+ ir_swizzle *rhs = new(ctx) ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i],
+ swiz[5 - i], swiz[6 - i],
+ column_type->vector_elements);
+
+ ir_constant *const idx = new(ctx) ir_constant(int(i));
+ ir_dereference *const lhs =
+ new(ctx) ir_dereference_array(declarations[16], idx);
+
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
+ instructions->push_tail(inst);
+ }
+
+ ir_dereference *const retval = new(ctx) ir_dereference_variable(declarations[16]);
+ inst = new(ctx) ir_return(retval);
+ instructions->push_tail(inst);
+}
+
+
+/**
+ * Generate the body of a vector constructor that takes multiple scalars
+ */
+static void
+generate_mat_body_from_N_scalars(void *ctx,
+ exec_list *instructions,
+ ir_variable **declarations)
+{
+ ir_instruction *inst;
+ const glsl_type *const row_type = declarations[16]->type->row_type();
+ const glsl_type *const column_type = declarations[16]->type->column_type();
+
+ /* Generate an assignment of each parameter to a single component of
+ * of a particular column of __retval and return __retval.
+ */
+ for (unsigned i = 0; i < column_type->vector_elements; i++) {
+ for (unsigned j = 0; j < row_type->vector_elements; j++) {
+ ir_constant *row_index = new(ctx) ir_constant(int(i));
+ ir_dereference *const row_access =
+ new(ctx) ir_dereference_array(declarations[16], row_index);
+
+ ir_swizzle *component_access = new(ctx) ir_swizzle(row_access,
+ j, 0, 0, 0, 1);
+
+ const unsigned param = (i * row_type->vector_elements) + j;
+ ir_dereference *const rhs =
+ new(ctx) ir_dereference_variable(declarations[param]);
+
+ inst = new(ctx) ir_assignment(component_access, rhs, NULL);
+ instructions->push_tail(inst);
+ }
+ }
+
+ ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
+
+ inst = new(ctx) ir_return(retval);
+ instructions->push_tail(inst);
+}
+
+
+/**
+ * Generate the constructors for a set of GLSL types
+ *
+ * Constructor implementations are added to \c instructions, and the symbols
+ * are added to \c symtab.
+ */
+static void
+generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
+ unsigned num_types, exec_list *instructions)
+{
+ void *ctx = symtab;
+ ir_variable *declarations[17];
+
+ for (unsigned i = 0; i < num_types; i++) {
+ /* Only numeric and boolean vectors and matrices get constructors here.
+ * Structures need to be handled elsewhere. It is expected that scalar
+ * constructors are never actually called, so they are not generated.
+ */
+ if (!types[i].is_numeric() && !types[i].is_boolean())
+ continue;
+
+ if (types[i].is_scalar())
+ continue;
+
+ /* Generate the function block, add it to the symbol table, and emit it.
+ */
+ ir_function *const f = new(ctx) ir_function(types[i].name);
+
+ bool added = symtab->add_function(types[i].name, f);
+ assert(added);
+
+ instructions->push_tail(f);
+
+ /* Each type has several basic constructors. The total number of forms
+ * depends on the derived type.
+ *
+ * Vectors: 1 scalar, N scalars
+ * Matrices: 1 scalar, NxM scalars
+ *
+ * Several possible types of constructors are not included in this list.
+ *
+ * Scalar constructors are not included. The expectation is that the
+ * IR generator won't actually generate these as constructor calls. The
+ * expectation is that it will just generate the necessary type
+ * conversion.
+ *
+ * Matrix contructors from matrices are also not included. The
+ * expectation is that the IR generator will generate a call to the
+ * appropriate from-scalars constructor.
+ */
+ ir_function_signature *const sig =
+ generate_constructor_intro(ctx, &types[i], 1, declarations);
+ f->add_signature(sig);
+
+ if (types[i].is_vector()) {
+ generate_vec_body_from_scalar(ctx, &sig->body, declarations);
+
+ ir_function_signature *const vec_sig =
+ generate_constructor_intro(ctx,
+ &types[i], types[i].vector_elements,
+ declarations);
+ f->add_signature(vec_sig);
+
+ generate_vec_body_from_N_scalars(ctx, &vec_sig->body, declarations);
+ } else {
+ assert(types[i].is_matrix());
+
+ generate_mat_body_from_scalar(ctx, &sig->body, declarations);
+
+ ir_function_signature *const mat_sig =
+ generate_constructor_intro(ctx,
+ &types[i],
+ (types[i].vector_elements
+ * types[i].matrix_columns),
+ declarations);
+ f->add_signature(mat_sig);
+
+ generate_mat_body_from_N_scalars(ctx, &mat_sig->body, declarations);
+ }
+ }
+}
+
+
+void
+generate_110_constructors(glsl_symbol_table *symtab, exec_list *instructions)
+{
+ generate_constructor(symtab, builtin_core_types,
+ Elements(builtin_core_types), instructions);
+}
+
+
+void
+generate_120_constructors(glsl_symbol_table *symtab, exec_list *instructions)
+{
+ generate_110_constructors(symtab, instructions);
+
+ generate_constructor(symtab, builtin_120_types,
+ Elements(builtin_120_types), instructions);
+}
+
+
+void
+generate_130_constructors(glsl_symbol_table *symtab, exec_list *instructions)
+{
+ generate_120_constructors(symtab, instructions);
+
+ generate_constructor(symtab, builtin_130_types,
+ Elements(builtin_130_types), instructions);
+}
+
+
+void
+_mesa_glsl_initialize_constructors(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ switch (state->language_version) {
+ case 110:
+ generate_110_constructors(state->symbols, instructions);
+ break;
+ case 120:
+ generate_120_constructors(state->symbols, instructions);
+ break;
+ case 130:
+ generate_130_constructors(state->symbols, instructions);
+ break;
+ default:
+ /* error */
+ break;
+ }
+}
+
+
+glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) :
+ base_type(GLSL_TYPE_ARRAY),
+ sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+ sampler_type(0),
+ vector_elements(0), matrix_columns(0),
+ name(NULL), length(length)
+{
+ this->fields.array = array;
+
+ /* Allow a maximum of 10 characters for the array size. This is enough
+ * for 32-bits of ~0. The extra 3 are for the '[', ']', and terminating
+ * NUL.
+ */
+ const unsigned name_length = strlen(array->name) + 10 + 3;
+ char *const n = (char *) talloc_size(ctx, name_length);
+
+ if (length == 0)
+ snprintf(n, name_length, "%s[]", array->name);
+ else
+ snprintf(n, name_length, "%s[%u]", array->name, length);
+
+ this->name = n;
+}
+
+
+const glsl_type *
+glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
+{
+ if (base_type == GLSL_TYPE_VOID)
+ return &void_type;
+
+ if ((rows < 1) || (rows > 4) || (columns < 1) || (columns > 4))
+ return error_type;
+
+ /* Treat GLSL vectors as Nx1 matrices.
+ */
+ if (columns == 1) {
+ switch (base_type) {
+ case GLSL_TYPE_UINT:
+ return uint_type + (rows - 1);
+ case GLSL_TYPE_INT:
+ return int_type + (rows - 1);
+ case GLSL_TYPE_FLOAT:
+ return float_type + (rows - 1);
+ case GLSL_TYPE_BOOL:
+ return bool_type + (rows - 1);
+ default:
+ return error_type;
+ }
+ } else {
+ if ((base_type != GLSL_TYPE_FLOAT) || (rows == 1))
+ return error_type;
+
+ /* GLSL matrix types are named mat{COLUMNS}x{ROWS}. Only the following
+ * combinations are valid:
+ *
+ * 1 2 3 4
+ * 1
+ * 2 x x x
+ * 3 x x x
+ * 4 x x x
+ */
+#define IDX(c,r) (((c-1)*3) + (r-1))
+
+ switch (IDX(columns, rows)) {
+ case IDX(2,2): return mat2_type;
+ case IDX(2,3): return mat2x3_type;
+ case IDX(2,4): return mat2x4_type;
+ case IDX(3,2): return mat3x2_type;
+ case IDX(3,3): return mat3_type;
+ case IDX(3,4): return mat3x4_type;
+ case IDX(4,2): return mat4x2_type;
+ case IDX(4,3): return mat4x3_type;
+ case IDX(4,4): return mat4_type;
+ default: return error_type;
+ }
+ }
+
+ assert(!"Should not get here.");
+ return error_type;
+}
+
+
+int
+glsl_type::array_key_compare(const void *a, const void *b)
+{
+ const glsl_type *const key1 = (glsl_type *) a;
+ const glsl_type *const key2 = (glsl_type *) b;
+
+ /* Return zero is the types match (there is zero difference) or non-zero
+ * otherwise.
+ */
+ return ((key1->fields.array == key2->fields.array)
+ && (key1->length == key2->length)) ? 0 : 1;
+}
+
+
+unsigned
+glsl_type::array_key_hash(const void *a)
+{
+ const glsl_type *const key = (glsl_type *) a;
+
+ const struct {
+ const glsl_type *t;
+ unsigned l;
+ char nul;
+ } hash_key = {
+ key->fields.array,
+ key->length,
+ '\0'
+ };
+
+ return hash_table_string_hash(& hash_key);
+}
+
+
+const glsl_type *
+glsl_type::get_array_instance(void *ctx, const glsl_type *base,
+ unsigned array_size)
+{
+ const glsl_type key(ctx, base, array_size);
+
+ if (array_types == NULL) {
+ array_types = hash_table_ctor(64, array_key_hash, array_key_compare);
+ }
+
+ const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key);
+ if (t == NULL) {
+ t = new(ctx) glsl_type(ctx, base, array_size);
+
+ hash_table_insert(array_types, (void *) t, t);
+ }
+
+ assert(t->base_type == GLSL_TYPE_ARRAY);
+ assert(t->length == array_size);
+ assert(t->fields.array == base);
+
+ return t;
+}
+
+
+const glsl_type *
+glsl_type::field_type(const char *name) const
+{
+ if (this->base_type != GLSL_TYPE_STRUCT)
+ return error_type;
+
+ for (unsigned i = 0; i < this->length; i++) {
+ if (strcmp(name, this->fields.structure[i].name) == 0)
+ return this->fields.structure[i].type;
+ }
+
+ return error_type;
+}
+
+
+int
+glsl_type::field_index(const char *name) const
+{
+ if (this->base_type != GLSL_TYPE_STRUCT)
+ return -1;
+
+ for (unsigned i = 0; i < this->length; i++) {
+ if (strcmp(name, this->fields.structure[i].name) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+
+unsigned
+glsl_type::component_slots() const
+{
+ switch (this->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ return this->components();
+
+ case GLSL_TYPE_STRUCT: {
+ unsigned size = 0;
+
+ for (unsigned i = 0; i < this->length; i++)
+ size += this->fields.structure[i].type->component_slots();
+
+ return size;
+ }
+
+ case GLSL_TYPE_ARRAY:
+ return this->length * this->fields.array->component_slots();
+
+ default:
+ return 0;
+ }
+}
--- /dev/null
+/* -*- 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 GLSL_TYPES_H
+#define GLSL_TYPES_H
+
+#include <cstring>
+#include <cassert>
+
+extern "C" {
+#include <talloc.h>
+}
+
+#define GLSL_TYPE_UINT 0
+#define GLSL_TYPE_INT 1
+#define GLSL_TYPE_FLOAT 2
+#define GLSL_TYPE_BOOL 3
+#define GLSL_TYPE_SAMPLER 4
+#define GLSL_TYPE_STRUCT 5
+#define GLSL_TYPE_ARRAY 6
+#define GLSL_TYPE_FUNCTION 7
+#define GLSL_TYPE_VOID 8
+#define GLSL_TYPE_ERROR 9
+
+enum glsl_sampler_dim {
+ GLSL_SAMPLER_DIM_1D = 0,
+ GLSL_SAMPLER_DIM_2D,
+ GLSL_SAMPLER_DIM_3D,
+ GLSL_SAMPLER_DIM_CUBE,
+ GLSL_SAMPLER_DIM_RECT,
+ GLSL_SAMPLER_DIM_BUF
+};
+
+
+struct glsl_type {
+ unsigned base_type:4;
+
+ unsigned sampler_dimensionality:3;
+ unsigned sampler_shadow:1;
+ unsigned sampler_array:1;
+ unsigned sampler_type:2; /**< Type of data returned using this sampler.
+ * only \c GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
+ * and \c GLSL_TYPE_UINT are valid.
+ */
+
+ /* 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 *type;
+
+ type = talloc_size(ctx, size);
+ assert(type != NULL);
+
+ return type;
+ }
+
+ /* If the user *does* call delete, that's OK, we will just
+ * talloc_free in that case. */
+ static void operator delete(void *type)
+ {
+ talloc_free(type);
+ }
+
+ /**
+ * \name Vector and matrix element counts
+ *
+ * For scalars, each of these values will be 1. For non-numeric types
+ * these will be 0.
+ */
+ /*@{*/
+ unsigned vector_elements:3; /**< 1, 2, 3, or 4 vector elements. */
+ unsigned matrix_columns:3; /**< 1, 2, 3, or 4 matrix columns. */
+ /*@}*/
+
+ /**
+ * Name of the data type
+ *
+ * This may be \c NULL for anonymous structures, for arrays, or for
+ * function types.
+ */
+ const char *name;
+
+ /**
+ * For \c GLSL_TYPE_ARRAY, this is the length of the array. For
+ * \c GLSL_TYPE_STRUCT, it is the number of elements in the structure and
+ * the number of values pointed to by \c fields.structure (below).
+ *
+ * For \c GLSL_TYPE_FUNCTION, it is the number of parameters to the
+ * function. The return value from a function is implicitly the first
+ * parameter. The types of the parameters are stored in
+ * \c fields.parameters (below).
+ */
+ unsigned length;
+
+ /**
+ * Subtype of composite data types.
+ */
+ union {
+ const struct glsl_type *array; /**< Type of array elements. */
+ const struct glsl_type *parameters; /**< Parameters to function. */
+ const struct glsl_struct_field *structure;/**< List of struct fields. */
+ } fields;
+
+
+ /**
+ * \name Pointers to various public type singletons
+ */
+ /*@{*/
+ static const glsl_type *const error_type;
+ static const glsl_type *const int_type;
+ static const glsl_type *const ivec4_type;
+ static const glsl_type *const uint_type;
+ static const glsl_type *const uvec4_type;
+ static const glsl_type *const float_type;
+ static const glsl_type *const vec2_type;
+ static const glsl_type *const vec3_type;
+ static const glsl_type *const vec4_type;
+ static const glsl_type *const bool_type;
+ static const glsl_type *const mat2_type;
+ static const glsl_type *const mat2x3_type;
+ static const glsl_type *const mat2x4_type;
+ static const glsl_type *const mat3x2_type;
+ static const glsl_type *const mat3_type;
+ static const glsl_type *const mat3x4_type;
+ static const glsl_type *const mat4x2_type;
+ static const glsl_type *const mat4x3_type;
+ static const glsl_type *const mat4_type;
+ /*@}*/
+
+
+ glsl_type(unsigned base_type, unsigned vector_elements,
+ unsigned matrix_columns, const char *name) :
+ base_type(base_type),
+ sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+ sampler_type(0),
+ vector_elements(vector_elements), matrix_columns(matrix_columns),
+ name(name),
+ length(0)
+ {
+ /* Neither dimension is zero or both dimensions are zero.
+ */
+ assert((vector_elements == 0) == (matrix_columns == 0));
+ memset(& fields, 0, sizeof(fields));
+ }
+
+ glsl_type(enum glsl_sampler_dim dim, bool shadow, bool array,
+ unsigned type, const char *name) :
+ base_type(GLSL_TYPE_SAMPLER),
+ sampler_dimensionality(dim), sampler_shadow(shadow),
+ sampler_array(array), sampler_type(type),
+ vector_elements(0), matrix_columns(0),
+ name(name),
+ length(0)
+ {
+ memset(& fields, 0, sizeof(fields));
+ }
+
+ glsl_type(const glsl_struct_field *fields, unsigned num_fields,
+ const char *name) :
+ base_type(GLSL_TYPE_STRUCT),
+ sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+ sampler_type(0),
+ vector_elements(0), matrix_columns(0),
+ name(name),
+ length(num_fields)
+ {
+ this->fields.structure = fields;
+ }
+
+ /**
+ * For numeric and boolean derrived types returns the basic scalar type
+ *
+ * If the type is a numeric or boolean scalar, vector, or matrix type,
+ * this function gets the scalar type of the individual components. For
+ * all other types, including arrays of numeric or boolean types, the
+ * error type is returned.
+ */
+ const glsl_type *get_base_type() const;
+
+ /**
+ * Query the type of elements in an array
+ *
+ * \return
+ * Pointer to the type of elements in the array for array types, or \c NULL
+ * for non-array types.
+ */
+ const glsl_type *element_type() const
+ {
+ return is_array() ? fields.array : NULL;
+ }
+
+ /**
+ * Get the instance of a built-in scalar, vector, or matrix type
+ */
+ static const glsl_type *get_instance(unsigned base_type, unsigned rows,
+ unsigned columns);
+
+ /**
+ * Get the instance of an array type
+ */
+ static const glsl_type *get_array_instance(void *ctx,
+ const glsl_type *base,
+ unsigned elements);
+
+ /**
+ * Generate the constructor for this type and add it to the symbol table
+ */
+ class ir_function *generate_constructor(class glsl_symbol_table *) const;
+
+ /**
+ * Query the total number of scalars that make up a scalar, vector or matrix
+ */
+ unsigned components() const
+ {
+ return vector_elements * matrix_columns;
+ }
+
+ /**
+ * Calculate the number of components slots required to hold this type
+ *
+ * This is used to determine how many uniform or varying locations a type
+ * might occupy.
+ */
+ unsigned component_slots() const;
+
+
+ /**
+ * Query whether or not a type is a scalar (non-vector and non-matrix).
+ */
+ bool is_scalar() const
+ {
+ return (vector_elements == 1)
+ && (base_type >= GLSL_TYPE_UINT)
+ && (base_type <= GLSL_TYPE_BOOL);
+ }
+
+ /**
+ * Query whether or not a type is a vector
+ */
+ bool is_vector() const
+ {
+ return (vector_elements > 1)
+ && (matrix_columns == 1)
+ && (base_type >= GLSL_TYPE_UINT)
+ && (base_type <= GLSL_TYPE_BOOL);
+ }
+
+ /**
+ * Query whether or not a type is a matrix
+ */
+ bool is_matrix() const
+ {
+ /* GLSL only has float matrices. */
+ return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT);
+ }
+
+ /**
+ * Query whether or not a type is a non-array numeric type
+ */
+ bool is_numeric() const
+ {
+ return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_FLOAT);
+ }
+
+ /**
+ * Query whether or not a type is an integral type
+ */
+ bool is_integer() const
+ {
+ return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT);
+ }
+
+ /**
+ * Query whether or not a type is a float type
+ */
+ bool is_float() const
+ {
+ return base_type == GLSL_TYPE_FLOAT;
+ }
+
+ /**
+ * Query whether or not a type is a non-array boolean type
+ */
+ bool is_boolean() const
+ {
+ return base_type == GLSL_TYPE_BOOL;
+ }
+
+ /**
+ * Query whether or not a type is a sampler
+ */
+ bool is_sampler() const
+ {
+ return base_type == GLSL_TYPE_SAMPLER;
+ }
+
+ /**
+ * Query whether or not a type is an array
+ */
+ bool is_array() const
+ {
+ return base_type == GLSL_TYPE_ARRAY;
+ }
+
+ /**
+ * Query whether or not a type is a record
+ */
+ bool is_record() const
+ {
+ return base_type == GLSL_TYPE_STRUCT;
+ }
+
+ /**
+ * Query whether or not a type is the void type singleton.
+ */
+ bool is_void() const
+ {
+ return base_type == GLSL_TYPE_VOID;
+ }
+
+ /**
+ * Query whether or not a type is the error type singleton.
+ */
+ bool is_error() const
+ {
+ return base_type == GLSL_TYPE_ERROR;
+ }
+
+ /**
+ * Query the full type of a matrix row
+ *
+ * \return
+ * If the type is not a matrix, \c glsl_type::error_type is returned.
+ * Otherwise a type matching the rows of the matrix is returned.
+ */
+ const glsl_type *row_type() const
+ {
+ return is_matrix()
+ ? get_instance(base_type, matrix_columns, 1)
+ : error_type;
+ }
+
+ /**
+ * Query the full type of a matrix column
+ *
+ * \return
+ * If the type is not a matrix, \c glsl_type::error_type is returned.
+ * Otherwise a type matching the columns of the matrix is returned.
+ */
+ const glsl_type *column_type() const
+ {
+ return is_matrix()
+ ? get_instance(base_type, vector_elements, 1)
+ : error_type;
+ }
+
+
+ /**
+ * Get the type of a structure field
+ *
+ * \return
+ * Pointer to the type of the named field. If the type is not a structure
+ * or the named field does not exist, \c glsl_type::error_type is returned.
+ */
+ const glsl_type *field_type(const char *name) const;
+
+
+ /**
+ * Get the location of a filed within a record type
+ */
+ int field_index(const char *name) const;
+
+
+ /**
+ * Query the number of elements in an array type
+ *
+ * \return
+ * The number of elements in the array for array types or -1 for non-array
+ * types. If the number of elements in the array has not yet been declared,
+ * zero is returned.
+ */
+ int array_size() const
+ {
+ return is_array() ? length : -1;
+ }
+
+private:
+ /**
+ * Constructor for array types
+ */
+ glsl_type(void *ctx, const glsl_type *array, unsigned length);
+
+ /** Hash table containing the known array types. */
+ static struct hash_table *array_types;
+
+ static int array_key_compare(const void *a, const void *b);
+ static unsigned array_key_hash(const void *key);
+};
+
+struct glsl_struct_field {
+ const struct glsl_type *type;
+ const char *name;
+};
+
+struct _mesa_glsl_parse_state;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void
+_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
+
+extern void
+_mesa_glsl_initialize_constructors(struct exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GLSL_TYPES_H */
--- /dev/null
+/*
+ * Copyright © 2008 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.
+ */
+
+/**
+ * \file hash_table.c
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "hash_table.h"
+
+struct node {
+ struct node *next;
+ struct node *prev;
+};
+
+struct hash_table {
+ hash_func_t hash;
+ hash_compare_func_t compare;
+
+ unsigned num_buckets;
+ struct node buckets[1];
+};
+
+
+struct hash_node {
+ struct node link;
+ const void *key;
+ void *data;
+};
+
+
+struct hash_table *
+hash_table_ctor(unsigned num_buckets, hash_func_t hash,
+ hash_compare_func_t compare)
+{
+ struct hash_table *ht;
+ unsigned i;
+
+
+ if (num_buckets < 16) {
+ num_buckets = 16;
+ }
+
+ ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1)
+ * sizeof(ht->buckets[0])));
+ if (ht != NULL) {
+ ht->hash = hash;
+ ht->compare = compare;
+ ht->num_buckets = num_buckets;
+
+ for (i = 0; i < num_buckets; i++) {
+ make_empty_list(& ht->buckets[i]);
+ }
+ }
+
+ return ht;
+}
+
+
+void
+hash_table_dtor(struct hash_table *ht)
+{
+ hash_table_clear(ht);
+ _mesa_free(ht);
+}
+
+
+void
+hash_table_clear(struct hash_table *ht)
+{
+ struct node *node;
+ struct node *temp;
+ unsigned i;
+
+
+ for (i = 0; i < ht->num_buckets; i++) {
+ foreach_s(node, temp, & ht->buckets[i]) {
+ remove_from_list(node);
+ _mesa_free(node);
+ }
+
+ assert(is_empty_list(& ht->buckets[i]));
+ }
+}
+
+
+void *
+hash_table_find(struct hash_table *ht, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct node *node;
+
+ foreach(node, & ht->buckets[bucket]) {
+ struct hash_node *hn = (struct hash_node *) node;
+
+ if ((*ht->compare)(hn->key, key) == 0) {
+ return hn->data;
+ }
+ }
+
+ return NULL;
+}
+
+
+void
+hash_table_insert(struct hash_table *ht, void *data, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct hash_node *node;
+
+ node = _mesa_calloc(sizeof(*node));
+
+ node->data = data;
+ node->key = key;
+
+ insert_at_head(& ht->buckets[bucket], & node->link);
+}
+
+
+unsigned
+hash_table_string_hash(const void *key)
+{
+ const char *str = (const char *) key;
+ unsigned hash = 5381;
+
+
+ while (*str != '\0') {
+ hash = (hash * 33) + *str;
+ str++;
+ }
+
+ return hash;
+}
--- /dev/null
+/*
+ * Copyright © 2008 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.
+ */
+
+/**
+ * \file hash_table.h
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#ifndef HASH_TABLE_H
+#define HASH_TABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+
+struct hash_table;
+
+typedef unsigned (*hash_func_t)(const void *key);
+typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
+
+/**
+ * Hash table constructor
+ *
+ * Creates a hash table with the specified number of buckets. The supplied
+ * \c hash and \c compare routines are used when adding elements to the table
+ * and when searching for elements in the table.
+ *
+ * \param num_buckets Number of buckets (bins) in the hash table.
+ * \param hash Function used to compute hash value of input keys.
+ * \param compare Function used to compare keys.
+ */
+extern struct hash_table *hash_table_ctor(unsigned num_buckets,
+ hash_func_t hash, hash_compare_func_t compare);
+
+
+/**
+ * Release all memory associated with a hash table
+ *
+ * \warning
+ * This function cannot release memory occupied either by keys or data.
+ */
+extern void hash_table_dtor(struct hash_table *ht);
+
+
+/**
+ * Flush all entries from a hash table
+ *
+ * \param ht Table to be cleared of its entries.
+ */
+extern void hash_table_clear(struct hash_table *ht);
+
+
+/**
+ * Search a hash table for a specific element
+ *
+ * \param ht Table to be searched
+ * \param key Key of the desired element
+ *
+ * \return
+ * The \c data value supplied to \c hash_table_insert when the element with
+ * the matching key was added. If no matching key exists in the table,
+ * \c NULL is returned.
+ */
+extern void *hash_table_find(struct hash_table *ht, const void *key);
+
+
+/**
+ * Add an element to a hash table
+ */
+extern void hash_table_insert(struct hash_table *ht, void *data,
+ const void *key);
+
+
+/**
+ * Compute hash value of a string
+ *
+ * Computes the hash value of a string using the DJB2 algorithm developed by
+ * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
+ * a time. I was unable to find the original posting in the archives.
+ *
+ * \param key Pointer to a NUL terminated string to be hashed.
+ *
+ * \sa hash_table_string_compare
+ */
+extern unsigned hash_table_string_hash(const void *key);
+
+
+/**
+ * Compare two strings used as keys
+ *
+ * This is just a macro wrapper around \c strcmp.
+ *
+ * \sa hash_table_string_hash
+ */
+#define hash_table_string_compare ((hash_compare_func_t) strcmp)
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* HASH_TABLE_H */
--- /dev/null
+/*
+ * 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 "ir.h"
+#include "main/imports.h"
+#include "symbol_table.h"
+#include "glsl_parser_extras.h"
+#include "ast.h"
+#include "glsl_types.h"
+
+struct ir_rvalue *
+_mesa_ast_field_selection_to_hir(const ast_expression *expr,
+ exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = talloc_parent(state);
+ ir_rvalue *result = NULL;
+ ir_rvalue *op;
+
+ op = expr->subexpressions[0]->hir(instructions, state);
+
+ /* There are two kinds of field selection. There is the selection of a
+ * specific field from a structure, and there is the selection of a
+ * swizzle / mask from a vector. Which is which is determined entirely
+ * by the base type of the thing to which the field selection operator is
+ * being applied.
+ */
+ YYLTYPE loc = expr->get_location();
+ if (op->type->is_error()) {
+ /* silently propagate the error */
+ } else if (op->type->is_vector()) {
+ ir_swizzle *swiz = ir_swizzle::create(op,
+ expr->primary_expression.identifier,
+ op->type->vector_elements);
+ if (swiz != NULL) {
+ result = swiz;
+ } else {
+ /* FINISHME: Logging of error messages should be moved into
+ * FINISHME: ir_swizzle::create. This allows the generation of more
+ * FINISHME: specific error messages.
+ */
+ _mesa_glsl_error(& loc, state, "Invalid swizzle / mask `%s'",
+ expr->primary_expression.identifier);
+ }
+ } else if (op->type->base_type == GLSL_TYPE_STRUCT) {
+ result = new(ctx) ir_dereference_record(op,
+ expr->primary_expression.identifier);
+
+ if (result->type->is_error()) {
+ _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
+ "structure",
+ expr->primary_expression.identifier);
+ }
+ } else {
+ _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
+ "non-structure / non-vector.",
+ expr->primary_expression.identifier);
+ }
+
+ return result ? result : ir_call::get_error_instruction(ctx);
+}
--- /dev/null
+/*
+ * 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 <string.h>
+#include "main/imports.h"
+#include "ir.h"
+#include "ir_visitor.h"
+#include "glsl_types.h"
+
+ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
+ ir_rvalue *condition)
+{
+ this->lhs = lhs;
+ this->rhs = rhs;
+ this->condition = condition;
+}
+
+
+ir_expression::ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *op0, ir_rvalue *op1)
+{
+ this->type = type;
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = op1;
+}
+
+unsigned int
+ir_expression::get_num_operands(ir_expression_operation op)
+{
+/* Update ir_print_visitor.cpp when updating this list. */
+ const int num_operands[] = {
+ 1, /* ir_unop_bit_not */
+ 1, /* ir_unop_logic_not */
+ 1, /* ir_unop_neg */
+ 1, /* ir_unop_abs */
+ 1, /* ir_unop_sign */
+ 1, /* ir_unop_rcp */
+ 1, /* ir_unop_rsq */
+ 1, /* ir_unop_sqrt */
+ 1, /* ir_unop_exp */
+ 1, /* ir_unop_log */
+ 1, /* ir_unop_exp2 */
+ 1, /* ir_unop_log2 */
+ 1, /* ir_unop_f2i */
+ 1, /* ir_unop_i2f */
+ 1, /* ir_unop_f2b */
+ 1, /* ir_unop_b2f */
+ 1, /* ir_unop_i2b */
+ 1, /* ir_unop_b2i */
+ 1, /* ir_unop_u2f */
+
+ 1, /* ir_unop_trunc */
+ 1, /* ir_unop_ceil */
+ 1, /* ir_unop_floor */
+
+ 1, /* ir_unop_sin */
+ 1, /* ir_unop_cos */
+
+ 1, /* ir_unop_dFdx */
+ 1, /* ir_unop_dFdy */
+
+ 2, /* ir_binop_add */
+ 2, /* ir_binop_sub */
+ 2, /* ir_binop_mul */
+ 2, /* ir_binop_div */
+ 2, /* ir_binop_mod */
+
+ 2, /* ir_binop_less */
+ 2, /* ir_binop_greater */
+ 2, /* ir_binop_lequal */
+ 2, /* ir_binop_gequal */
+ 2, /* ir_binop_equal */
+ 2, /* ir_binop_nequal */
+
+ 2, /* ir_binop_lshift */
+ 2, /* ir_binop_rshift */
+ 2, /* ir_binop_bit_and */
+ 2, /* ir_binop_bit_xor */
+ 2, /* ir_binop_bit_or */
+
+ 2, /* ir_binop_logic_and */
+ 2, /* ir_binop_logic_xor */
+ 2, /* ir_binop_logic_or */
+
+ 2, /* ir_binop_dot */
+ 2, /* ir_binop_min */
+ 2, /* ir_binop_max */
+
+ 2, /* ir_binop_pow */
+ };
+
+ assert(sizeof(num_operands) / sizeof(num_operands[0]) == ir_binop_pow + 1);
+
+ return num_operands[op];
+}
+
+static const char *const operator_strs[] = {
+ "~",
+ "!",
+ "neg",
+ "abs",
+ "sign",
+ "rcp",
+ "rsq",
+ "sqrt",
+ "exp",
+ "log",
+ "exp2",
+ "log2",
+ "f2i",
+ "i2f",
+ "f2b",
+ "b2f",
+ "i2b",
+ "b2i",
+ "u2f",
+ "trunc",
+ "ceil",
+ "floor",
+ "sin",
+ "cos",
+ "dFdx",
+ "dFdy",
+ "+",
+ "-",
+ "*",
+ "/",
+ "%",
+ "<",
+ ">",
+ "<=",
+ ">=",
+ "==",
+ "!=",
+ "<<",
+ ">>",
+ "&",
+ "^",
+ "|",
+ "&&",
+ "^^",
+ "||",
+ "dot",
+ "min",
+ "max",
+ "pow",
+};
+
+const char *ir_expression::operator_string()
+{
+ assert((unsigned int) operation <=
+ sizeof(operator_strs) / sizeof(operator_strs[0]));
+ return operator_strs[operation];
+}
+
+ir_expression_operation
+ir_expression::get_operator(const char *str)
+{
+ const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]);
+ for (int op = 0; op < operator_count; op++) {
+ if (strcmp(str, operator_strs[op]) == 0)
+ return (ir_expression_operation) op;
+ }
+ return (ir_expression_operation) -1;
+}
+
+ir_constant::ir_constant()
+{
+ /* empty */
+}
+
+ir_constant::ir_constant(const struct glsl_type *type,
+ const ir_constant_data *data)
+{
+ assert((type->base_type >= GLSL_TYPE_UINT)
+ && (type->base_type <= GLSL_TYPE_BOOL));
+
+ this->type = type;
+ memcpy(& this->value, data, sizeof(this->value));
+}
+
+ir_constant::ir_constant(float f)
+{
+ this->type = glsl_type::float_type;
+ this->value.f[0] = f;
+}
+
+ir_constant::ir_constant(unsigned int u)
+{
+ this->type = glsl_type::uint_type;
+ this->value.u[0] = u;
+}
+
+ir_constant::ir_constant(int i)
+{
+ this->type = glsl_type::int_type;
+ this->value.i[0] = i;
+}
+
+ir_constant::ir_constant(bool b)
+{
+ this->type = glsl_type::bool_type;
+ this->value.b[0] = b;
+}
+
+ir_constant::ir_constant(const ir_constant *c, unsigned i)
+{
+ this->type = c->type->get_base_type();
+
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT: this->value.u[0] = c->value.u[i]; break;
+ case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break;
+ case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
+ case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break;
+ default: assert(!"Should not get here."); break;
+ }
+}
+
+ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
+{
+ this->type = type;
+
+ /* FINISHME: Support array types. */
+ assert(type->is_scalar() || type->is_vector() || type->is_matrix()
+ || type->is_record());
+
+ /* If the constant is a record, the types of each of the entries in
+ * value_list must be a 1-for-1 match with the structure components. Each
+ * entry must also be a constant. Just move the nodes from the value_list
+ * to the list in the ir_constant.
+ */
+ /* FINISHME: Should there be some type checking and / or assertions here? */
+ /* FINISHME: Should the new constant take ownership of the nodes from
+ * FINISHME: value_list, or should it make copies?
+ */
+ if (type->is_record()) {
+ value_list->move_nodes_to(& this->components);
+ return;
+ }
+
+
+ ir_constant *value = (ir_constant *) (value_list->head);
+
+ /* Use each component from each entry in the value_list to initialize one
+ * component of the constant being constructed.
+ */
+ for (unsigned i = 0; i < type->components(); /* empty */) {
+ assert(value->as_constant() != NULL);
+ assert(!value->is_tail_sentinal());
+
+ for (unsigned j = 0; j < value->type->components(); j++) {
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ this->value.u[i] = value->get_uint_component(j);
+ break;
+ case GLSL_TYPE_INT:
+ this->value.i[i] = value->get_int_component(j);
+ break;
+ case GLSL_TYPE_FLOAT:
+ this->value.f[i] = value->get_float_component(j);
+ break;
+ case GLSL_TYPE_BOOL:
+ this->value.b[i] = value->get_bool_component(j);
+ break;
+ default:
+ /* FINISHME: What to do? Exceptions are not the answer.
+ */
+ break;
+ }
+
+ i++;
+ if (i >= type->components())
+ break;
+ }
+
+ value = (ir_constant *) value->next;
+ }
+}
+
+bool
+ir_constant::get_bool_component(unsigned i) const
+{
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT: return this->value.u[i] != 0;
+ case GLSL_TYPE_INT: return this->value.i[i] != 0;
+ case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
+ case GLSL_TYPE_BOOL: return this->value.b[i];
+ default: assert(!"Should not get here."); break;
+ }
+
+ /* Must return something to make the compiler happy. This is clearly an
+ * error case.
+ */
+ return false;
+}
+
+float
+ir_constant::get_float_component(unsigned i) const
+{
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT: return (float) this->value.u[i];
+ case GLSL_TYPE_INT: return (float) this->value.i[i];
+ case GLSL_TYPE_FLOAT: return this->value.f[i];
+ case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0;
+ default: assert(!"Should not get here."); break;
+ }
+
+ /* Must return something to make the compiler happy. This is clearly an
+ * error case.
+ */
+ return 0.0;
+}
+
+int
+ir_constant::get_int_component(unsigned i) const
+{
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT: return this->value.u[i];
+ case GLSL_TYPE_INT: return this->value.i[i];
+ case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
+ case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
+ default: assert(!"Should not get here."); break;
+ }
+
+ /* Must return something to make the compiler happy. This is clearly an
+ * error case.
+ */
+ return 0;
+}
+
+unsigned
+ir_constant::get_uint_component(unsigned i) const
+{
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT: return this->value.u[i];
+ case GLSL_TYPE_INT: return this->value.i[i];
+ case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
+ case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
+ default: assert(!"Should not get here."); break;
+ }
+
+ /* Must return something to make the compiler happy. This is clearly an
+ * error case.
+ */
+ return 0;
+}
+
+
+ir_constant *
+ir_constant::get_record_field(const char *name)
+{
+ int idx = this->type->field_index(name);
+
+ if (idx < 0)
+ return NULL;
+
+ if (this->components.is_empty())
+ return NULL;
+
+ exec_node *node = this->components.head;
+ for (int i = 0; i < idx; i++) {
+ node = node->next;
+
+ /* If the end of the list is encountered before the element matching the
+ * requested field is found, return NULL.
+ */
+ if (node->is_tail_sentinal())
+ return NULL;
+ }
+
+ return (ir_constant *) node;
+}
+
+
+bool
+ir_constant::has_value(const ir_constant *c) const
+{
+ if (this->type != c->type)
+ return false;
+
+ /* FINISHME: This will probably also handle constant arrays as soon as those
+ * FINISHME: are supported.
+ */
+ if (this->type->base_type == GLSL_TYPE_STRUCT) {
+ const exec_node *a_node = this->components.head;
+ const exec_node *b_node = c->components.head;
+
+ while (!a_node->is_tail_sentinal()) {
+ assert(!b_node->is_tail_sentinal());
+
+ const ir_constant *const a_field = (ir_constant *) a_node;
+ const ir_constant *const b_field = (ir_constant *) b_node;
+
+ if (!a_field->has_value(b_field))
+ return false;
+
+ a_node = a_node->next;
+ b_node = b_node->next;
+ }
+
+ return true;
+ }
+
+ for (unsigned i = 0; i < this->type->components(); i++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT:
+ if (this->value.u[i] != c->value.u[i])
+ return false;
+ break;
+ case GLSL_TYPE_INT:
+ if (this->value.i[i] != c->value.i[i])
+ return false;
+ break;
+ case GLSL_TYPE_FLOAT:
+ if (this->value.f[i] != c->value.f[i])
+ return false;
+ break;
+ case GLSL_TYPE_BOOL:
+ if (this->value.b[i] != c->value.b[i])
+ return false;
+ break;
+ default:
+ assert(!"Should not get here.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ir_dereference_variable::ir_dereference_variable(ir_variable *var)
+{
+ this->var = var;
+ this->type = (var != NULL) ? var->type : glsl_type::error_type;
+}
+
+
+ir_dereference_array::ir_dereference_array(ir_rvalue *value,
+ ir_rvalue *array_index)
+{
+ this->array_index = array_index;
+ this->set_array(value);
+}
+
+
+ir_dereference_array::ir_dereference_array(ir_variable *var,
+ ir_rvalue *array_index)
+{
+ void *ctx = talloc_parent(var);
+
+ this->array_index = array_index;
+ this->set_array(new(ctx) ir_dereference_variable(var));
+}
+
+
+void
+ir_dereference_array::set_array(ir_rvalue *value)
+{
+ this->array = value;
+ this->type = glsl_type::error_type;
+
+ if (this->array != NULL) {
+ const glsl_type *const vt = this->array->type;
+
+ if (vt->is_array()) {
+ type = vt->element_type();
+ } else if (vt->is_matrix()) {
+ type = vt->column_type();
+ } else if (vt->is_vector()) {
+ type = vt->get_base_type();
+ }
+ }
+}
+
+
+ir_dereference_record::ir_dereference_record(ir_rvalue *value,
+ const char *field)
+{
+ this->record = value;
+ this->field = field;
+ this->type = (this->record != NULL)
+ ? this->record->type->field_type(field) : glsl_type::error_type;
+}
+
+
+ir_dereference_record::ir_dereference_record(ir_variable *var,
+ const char *field)
+{
+ void *ctx = talloc_parent(var);
+
+ this->record = new(ctx) ir_dereference_variable(var);
+ this->field = field;
+ this->type = (this->record != NULL)
+ ? this->record->type->field_type(field) : glsl_type::error_type;
+}
+
+
+bool
+ir_dereference::is_lvalue()
+{
+ ir_variable *var = this->variable_referenced();
+
+ /* Every l-value derference chain eventually ends in a variable.
+ */
+ if ((var == NULL) || var->read_only)
+ return false;
+
+ if (this->type->is_array() && !var->array_lvalue)
+ return false;
+
+ return true;
+}
+
+
+const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
+
+const char *ir_texture::opcode_string()
+{
+ assert((unsigned int) op <=
+ sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]));
+ return tex_opcode_strs[op];
+}
+
+ir_texture_opcode
+ir_texture::get_opcode(const char *str)
+{
+ const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
+ for (int op = 0; op < count; op++) {
+ if (strcmp(str, tex_opcode_strs[op]) == 0)
+ return (ir_texture_opcode) op;
+ }
+ return (ir_texture_opcode) -1;
+}
+
+
+void
+ir_texture::set_sampler(ir_dereference *sampler)
+{
+ assert(sampler != NULL);
+ this->sampler = sampler;
+
+ switch (sampler->type->sampler_type) {
+ case GLSL_TYPE_FLOAT:
+ this->type = glsl_type::vec4_type;
+ break;
+ case GLSL_TYPE_INT:
+ this->type = glsl_type::ivec4_type;
+ break;
+ case GLSL_TYPE_UINT:
+ this->type = glsl_type::uvec4_type;
+ break;
+ }
+}
+
+
+ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
+ unsigned w, unsigned count)
+ : val(val)
+{
+ assert((count >= 1) && (count <= 4));
+
+ const unsigned dup_mask = 0
+ | ((count > 1) ? ((1U << y) & ((1U << x) )) : 0)
+ | ((count > 2) ? ((1U << z) & ((1U << x) | (1U << y) )) : 0)
+ | ((count > 3) ? ((1U << w) & ((1U << x) | (1U << y) | (1U << z))) : 0);
+
+ assert(x <= 3);
+ assert(y <= 3);
+ assert(z <= 3);
+ assert(w <= 3);
+
+ mask.x = x;
+ mask.y = y;
+ mask.z = z;
+ mask.w = w;
+ mask.num_components = count;
+ mask.has_duplicates = dup_mask != 0;
+
+ /* Based on the number of elements in the swizzle and the base type
+ * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
+ * generate the type of the resulting value.
+ */
+ type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
+}
+
+ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
+{
+ this->val = val;
+ this->mask = mask;
+ this->type = glsl_type::get_instance(val->type->base_type,
+ mask.num_components, 1);
+}
+
+#define X 1
+#define R 5
+#define S 9
+#define I 13
+
+ir_swizzle *
+ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
+{
+ void *ctx = talloc_parent(val);
+
+ /* For each possible swizzle character, this table encodes the value in
+ * \c idx_map that represents the 0th element of the vector. For invalid
+ * swizzle characters (e.g., 'k'), a special value is used that will allow
+ * detection of errors.
+ */
+ static const unsigned char base_idx[26] = {
+ /* a b c d e f g h i j k l m */
+ R, R, I, I, I, I, R, I, I, I, I, I, I,
+ /* n o p q r s t u v w x y z */
+ I, I, S, S, R, S, S, I, I, X, X, X, X
+ };
+
+ /* Each valid swizzle character has an entry in the previous table. This
+ * table encodes the base index encoded in the previous table plus the actual
+ * index of the swizzle character. When processing swizzles, the first
+ * character in the string is indexed in the previous table. Each character
+ * in the string is indexed in this table, and the value found there has the
+ * value form the first table subtracted. The result must be on the range
+ * [0,3].
+ *
+ * For example, the string "wzyx" will get X from the first table. Each of
+ * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After
+ * subtraction, the swizzle values are { 3, 2, 1, 0 }.
+ *
+ * The string "wzrg" will get X from the first table. Each of the characters
+ * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the
+ * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range
+ * [0,3], the error is detected.
+ */
+ static const unsigned char idx_map[26] = {
+ /* a b c d e f g h i j k l m */
+ R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0,
+ /* n o p q r s t u v w x y z */
+ 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2
+ };
+
+ int swiz_idx[4] = { 0, 0, 0, 0 };
+ unsigned i;
+
+
+ /* Validate the first character in the swizzle string and look up the base
+ * index value as described above.
+ */
+ if ((str[0] < 'a') || (str[0] > 'z'))
+ return NULL;
+
+ const unsigned base = base_idx[str[0] - 'a'];
+
+
+ for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
+ /* Validate the next character, and, as described above, convert it to a
+ * swizzle index.
+ */
+ if ((str[i] < 'a') || (str[i] > 'z'))
+ return NULL;
+
+ swiz_idx[i] = idx_map[str[i] - 'a'] - base;
+ if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
+ return NULL;
+ }
+
+ if (str[i] != '\0')
+ return NULL;
+
+ return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
+ swiz_idx[3], i);
+}
+
+#undef X
+#undef R
+#undef S
+#undef I
+
+ir_variable *
+ir_swizzle::variable_referenced()
+{
+ return this->val->variable_referenced();
+}
+
+ir_variable::ir_variable(const struct glsl_type *type, const char *name)
+ : max_array_access(0), read_only(false), centroid(false), invariant(false),
+ shader_in(false), shader_out(false),
+ mode(ir_var_auto), interpolation(ir_var_smooth), array_lvalue(false)
+{
+ this->type = type;
+ this->name = name;
+ this->location = -1;
+ this->warn_extension = NULL;
+ this->constant_value = NULL;
+
+ if (type && type->base_type == GLSL_TYPE_SAMPLER)
+ this->read_only = true;
+}
+
+
+const char *
+ir_variable::interpolation_string() const
+{
+ if (!this->shader_in && !this->shader_out)
+ return "";
+
+ switch (this->interpolation) {
+ case ir_var_smooth: return "smooth";
+ case ir_var_flat: return "flat";
+ case ir_var_noperspective: return "noperspective";
+ }
+
+ assert(!"Should not get here.");
+ return "";
+}
+
+
+unsigned
+ir_variable::component_slots() const
+{
+ /* FINISHME: Sparsely accessed arrays require fewer slots. */
+ return this->type->component_slots();
+}
+
+
+ir_function_signature::ir_function_signature(const glsl_type *return_type)
+ : return_type(return_type), is_defined(false)
+{
+ /* empty */
+}
+
+
+const char *
+ir_function_signature::qualifiers_match(exec_list *params)
+{
+ exec_list_iterator iter_a = parameters.iterator();
+ exec_list_iterator iter_b = params->iterator();
+
+ /* check that the qualifiers match. */
+ while (iter_a.has_next()) {
+ ir_variable *a = (ir_variable *)iter_a.get();
+ ir_variable *b = (ir_variable *)iter_b.get();
+
+ if (a->read_only != b->read_only ||
+ a->mode != b->mode ||
+ a->interpolation != b->interpolation ||
+ a->centroid != b->centroid) {
+
+ /* parameter a's qualifiers don't match */
+ return a->name;
+ }
+
+ iter_a.next();
+ iter_b.next();
+ }
+ return NULL;
+}
+
+
+void
+ir_function_signature::replace_parameters(exec_list *new_params)
+{
+ /* Destroy all of the previous parameter information. If the previous
+ * parameter information comes from the function prototype, it may either
+ * specify incorrect parameter names or not have names at all.
+ */
+ foreach_iter(exec_list_iterator, iter, parameters) {
+ assert(((ir_instruction *) iter.get())->as_variable() != NULL);
+
+ iter.remove();
+ }
+
+ new_params->move_nodes_to(¶meters);
+}
+
+
+ir_function::ir_function(const char *name)
+ : name(name)
+{
+ /* empty */
+}
+
+
+ir_call *
+ir_call::get_error_instruction(void *ctx)
+{
+ ir_call *call = new(ctx) ir_call;
+
+ call->type = glsl_type::error_type;
+ return call;
+}
+
+void
+visit_exec_list(exec_list *list, ir_visitor *visitor)
+{
+ foreach_iter(exec_list_iterator, iter, *list) {
+ ((ir_instruction *)iter.get())->accept(visitor);
+ }
+}
+
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef IR_H
+#define IR_H
+
+#include <cstdio>
+#include <cstdlib>
+
+extern "C" {
+#include <talloc.h>
+}
+
+#include "list.h"
+#include "ir_visitor.h"
+#include "ir_hierarchical_visitor.h"
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+struct ir_program {
+ void *bong_hits;
+};
+
+/**
+ * Base class of all IR instructions
+ */
+class ir_instruction : public exec_node {
+public:
+ const struct glsl_type *type;
+
+ class ir_constant *constant_expression_value();
+
+ /** ir_print_visitor helper for debugging. */
+ void print(void) const;
+
+ virtual void accept(ir_visitor *) = 0;
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
+ virtual ir_instruction *clone(struct hash_table *ht) const = 0;
+
+ /**
+ * \name IR instruction downcast functions
+ *
+ * These functions either cast the object to a derived class or return
+ * \c NULL if the object's type does not match the specified derived class.
+ * Additional downcast functions will be added as needed.
+ */
+ /*@{*/
+ virtual class ir_variable * as_variable() { return NULL; }
+ virtual class ir_function * as_function() { return NULL; }
+ virtual class ir_dereference * as_dereference() { return NULL; }
+ virtual class ir_dereference_array * as_dereference_array() { return NULL; }
+ virtual class ir_rvalue * as_rvalue() { return NULL; }
+ virtual class ir_loop * as_loop() { return NULL; }
+ virtual class ir_assignment * as_assignment() { return NULL; }
+ virtual class ir_call * as_call() { return NULL; }
+ virtual class ir_return * as_return() { return NULL; }
+ virtual class ir_if * as_if() { return NULL; }
+ virtual class ir_swizzle * as_swizzle() { return NULL; }
+ virtual class ir_constant * as_constant() { return NULL; }
+ /*@}*/
+
+protected:
+ ir_instruction()
+ {
+ /* empty */
+ }
+};
+
+
+class ir_rvalue : public ir_instruction {
+public:
+ virtual ir_rvalue * as_rvalue()
+ {
+ return this;
+ }
+
+ virtual bool is_lvalue()
+ {
+ return false;
+ }
+
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced()
+ {
+ return NULL;
+ }
+
+
+ /**
+ * If an r-value is a reference to a whole variable, get that variable
+ *
+ * \return
+ * Pointer to a variable that is completely dereferenced by the r-value. If
+ * the r-value is not a dereference or the dereference does not access the
+ * entire variable (i.e., it's just one array element, struct field), \c NULL
+ * is returned.
+ */
+ virtual ir_variable *whole_variable_referenced()
+ {
+ return NULL;
+ }
+
+protected:
+ ir_rvalue()
+ {
+ /* empty */
+ }
+};
+
+
+enum ir_variable_mode {
+ ir_var_auto = 0,
+ ir_var_uniform,
+ ir_var_in,
+ ir_var_out,
+ ir_var_inout
+};
+
+enum ir_variable_interpolation {
+ ir_var_smooth = 0,
+ ir_var_flat,
+ ir_var_noperspective
+};
+
+
+class ir_variable : public ir_instruction {
+public:
+ ir_variable(const struct glsl_type *, const char *);
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ virtual ir_variable *as_variable()
+ {
+ return this;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+
+ /**
+ * Get the string value for the interpolation qualifier
+ *
+ * \return
+ * If none of \c shader_in or \c shader_out is set, an empty string will
+ * be returned. Otherwise the string that would be used in a shader to
+ * specify \c mode will be returned.
+ */
+ const char *interpolation_string() const;
+
+ /**
+ * Calculate the number of slots required to hold this variable
+ *
+ * This is used to determine how many uniform or varying locations a variable
+ * occupies. The count is in units of floating point components.
+ */
+ unsigned component_slots() const;
+
+ const char *name;
+
+ /**
+ * Highest element accessed with a constant expression array index
+ *
+ * Not used for non-array variables.
+ */
+ unsigned max_array_access;
+
+ unsigned read_only:1;
+ unsigned centroid:1;
+ unsigned invariant:1;
+ /** If the variable is initialized outside of the scope of the shader */
+ unsigned shader_in:1;
+ /**
+ * If the variable value is later used outside of the scope of the shader.
+ */
+ unsigned shader_out:1;
+
+ unsigned mode:3;
+ unsigned interpolation:2;
+
+ /**
+ * Flag that the whole array is assignable
+ *
+ * In GLSL 1.20 and later whole arrays are assignable (and comparable for
+ * equality). This flag enables this behavior.
+ */
+ unsigned array_lvalue:1;
+
+ /**
+ * Storage location of the base of this variable
+ *
+ * The precise meaning of this field depends on the nature of the variable.
+ *
+ * - Vertex shader input: one of the values from \c gl_vert_attrib.
+ * - Vertex shader output: one of the values from \c gl_vert_result.
+ * - Fragment shader input: one of the values from \c gl_frag_attrib.
+ * - Fragment shader output: one of the values from \c gl_frag_result.
+ * - Uniforms: Per-stage uniform slot number.
+ * - Other: This field is not currently used.
+ *
+ * If the variable is a uniform, shader input, or shader output, and the
+ * slot has not been assigned, the value will be -1.
+ */
+ int location;
+
+ /**
+ * Emit a warning if this variable is accessed.
+ */
+ const char *warn_extension;
+
+ /**
+ * Value assigned in the initializer of a variable declared "const"
+ */
+ ir_constant *constant_value;
+};
+
+
+/*@{*/
+/**
+ * The representation of a function instance; may be the full definition or
+ * simply a prototype.
+ */
+class ir_function_signature : public ir_instruction {
+ /* An ir_function_signature will be part of the list of signatures in
+ * an ir_function.
+ */
+public:
+ ir_function_signature(const glsl_type *return_type);
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ /**
+ * Get the name of the function for which this is a signature
+ */
+ const char *function_name() const;
+
+ /**
+ * Check whether the qualifiers match between this signature's parameters
+ * and the supplied parameter list. If not, returns the name of the first
+ * parameter with mismatched qualifiers (for use in error messages).
+ */
+ const char *qualifiers_match(exec_list *params);
+
+ /**
+ * Replace the current parameter list with the given one. This is useful
+ * if the current information came from a prototype, and either has invalid
+ * or missing parameter names.
+ */
+ void replace_parameters(exec_list *new_params);
+
+ /**
+ * Function return type.
+ *
+ * \note This discards the optional precision qualifier.
+ */
+ const struct glsl_type *return_type;
+
+ /**
+ * List of ir_variable of function parameters.
+ *
+ * This represents the storage. The paramaters passed in a particular
+ * call will be in ir_call::actual_paramaters.
+ */
+ struct exec_list parameters;
+
+ /** Whether or not this function has a body (which may be empty). */
+ unsigned is_defined:1;
+
+ /** Body of instructions in the function. */
+ struct exec_list body;
+
+private:
+ /** Function of which this signature is one overload. */
+ class ir_function *function;
+
+ friend class ir_function;
+};
+
+
+/**
+ * Header for tracking multiple overloaded functions with the same name.
+ * Contains a list of ir_function_signatures representing each of the
+ * actual functions.
+ */
+class ir_function : public ir_instruction {
+public:
+ ir_function(const char *name);
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ virtual ir_function *as_function()
+ {
+ return this;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ void add_signature(ir_function_signature *sig)
+ {
+ sig->function = this;
+ signatures.push_tail(sig);
+ }
+
+ /**
+ * Get an iterator for the set of function signatures
+ */
+ exec_list_iterator iterator()
+ {
+ return signatures.iterator();
+ }
+
+ /**
+ * Find a signature that matches a set of actual parameters, taking implicit
+ * conversions into account.
+ */
+ const ir_function_signature *matching_signature(exec_list *actual_param);
+
+ /**
+ * Find a signature that exactly matches a set of actual parameters without
+ * any implicit type conversions.
+ */
+ ir_function_signature *exact_matching_signature(exec_list *actual_ps);
+
+ /**
+ * Name of the function.
+ */
+ const char *name;
+
+private:
+ /**
+ * List of ir_function_signature for each overloaded function with this name.
+ */
+ struct exec_list signatures;
+};
+
+inline const char *ir_function_signature::function_name() const
+{
+ return function->name;
+}
+/*@}*/
+
+
+/**
+ * IR instruction representing high-level if-statements
+ */
+class ir_if : public ir_instruction {
+public:
+ ir_if(ir_rvalue *condition)
+ : condition(condition)
+ {
+ /* empty */
+ }
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ virtual ir_if *as_if()
+ {
+ return this;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ ir_rvalue *condition;
+ /** List of ir_instruction for the body of the then branch */
+ exec_list then_instructions;
+ /** List of ir_instruction for the body of the else branch */
+ exec_list else_instructions;
+};
+
+
+/**
+ * IR instruction representing a high-level loop structure.
+ */
+class ir_loop : public ir_instruction {
+public:
+ ir_loop() : from(NULL), to(NULL), increment(NULL), counter(NULL)
+ {
+ /* empty */
+ }
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ virtual ir_loop *as_loop()
+ {
+ return this;
+ }
+
+ /**
+ * Get an iterator for the instructions of the loop body
+ */
+ exec_list_iterator iterator()
+ {
+ return body_instructions.iterator();
+ }
+
+ /** List of ir_instruction that make up the body of the loop. */
+ exec_list body_instructions;
+
+ /**
+ * \name Loop counter and controls
+ */
+ /*@{*/
+ ir_rvalue *from;
+ ir_rvalue *to;
+ ir_rvalue *increment;
+ ir_variable *counter;
+ /*@}*/
+};
+
+
+class ir_assignment : public ir_rvalue {
+public:
+ ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ virtual ir_assignment * as_assignment()
+ {
+ return this;
+ }
+
+ /**
+ * Left-hand side of the assignment.
+ */
+ ir_rvalue *lhs;
+
+ /**
+ * Value being assigned
+ */
+ ir_rvalue *rhs;
+
+ /**
+ * Optional condition for the assignment.
+ */
+ ir_rvalue *condition;
+};
+
+/* Update ir_expression::num_operands() and operator_strs when
+ * updating this list.
+ */
+enum ir_expression_operation {
+ ir_unop_bit_not,
+ ir_unop_logic_not,
+ ir_unop_neg,
+ ir_unop_abs,
+ ir_unop_sign,
+ ir_unop_rcp,
+ ir_unop_rsq,
+ ir_unop_sqrt,
+ ir_unop_exp,
+ ir_unop_log,
+ ir_unop_exp2,
+ ir_unop_log2,
+ ir_unop_f2i, /**< Float-to-integer conversion. */
+ ir_unop_i2f, /**< Integer-to-float conversion. */
+ ir_unop_f2b, /**< Float-to-boolean conversion */
+ ir_unop_b2f, /**< Boolean-to-float conversion */
+ ir_unop_i2b, /**< int-to-boolean conversion */
+ ir_unop_b2i, /**< Boolean-to-int conversion */
+ ir_unop_u2f, /**< Unsigned-to-float conversion. */
+
+ /**
+ * \name Unary floating-point rounding operations.
+ */
+ /*@{*/
+ ir_unop_trunc,
+ ir_unop_ceil,
+ ir_unop_floor,
+ /*@}*/
+
+ /**
+ * \name Trigonometric operations.
+ */
+ /*@{*/
+ ir_unop_sin,
+ ir_unop_cos,
+ /*@}*/
+
+ /**
+ * \name Partial derivatives.
+ */
+ /*@{*/
+ ir_unop_dFdx,
+ ir_unop_dFdy,
+ /*@}*/
+
+ ir_binop_add,
+ ir_binop_sub,
+ ir_binop_mul,
+ ir_binop_div,
+ ir_binop_mod,
+
+ /**
+ * \name Binary comparison operators
+ */
+ /*@{*/
+ ir_binop_less,
+ ir_binop_greater,
+ ir_binop_lequal,
+ ir_binop_gequal,
+ ir_binop_equal,
+ ir_binop_nequal,
+ /*@}*/
+
+ /**
+ * \name Bit-wise binary operations.
+ */
+ /*@{*/
+ ir_binop_lshift,
+ ir_binop_rshift,
+ ir_binop_bit_and,
+ ir_binop_bit_xor,
+ ir_binop_bit_or,
+ /*@}*/
+
+ ir_binop_logic_and,
+ ir_binop_logic_xor,
+ ir_binop_logic_or,
+
+ ir_binop_dot,
+ ir_binop_min,
+ ir_binop_max,
+
+ ir_binop_pow
+};
+
+class ir_expression : public ir_rvalue {
+public:
+ ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *, ir_rvalue *);
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ static unsigned int get_num_operands(ir_expression_operation);
+ unsigned int get_num_operands() const
+ {
+ return get_num_operands(operation);
+ }
+
+ /**
+ * Return a string representing this expression's operator.
+ */
+ const char *operator_string();
+
+ /**
+ * Do a reverse-lookup to translate the given string into an operator.
+ */
+ static ir_expression_operation get_operator(const char *);
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ ir_expression_operation operation;
+ ir_rvalue *operands[2];
+};
+
+
+/**
+ * IR instruction representing a function call
+ */
+class ir_call : public ir_rvalue {
+public:
+ ir_call(const ir_function_signature *callee, exec_list *actual_parameters)
+ : callee(callee)
+ {
+ assert(callee->return_type != NULL);
+ type = callee->return_type;
+ actual_parameters->move_nodes_to(& this->actual_parameters);
+ }
+
+ virtual ir_instruction *clone(struct hash_table *ht) const;
+
+ virtual ir_call *as_call()
+ {
+ return this;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ /**
+ * Get a generic ir_call object when an error occurs
+ *
+ * Any allocation will be performed with 'ctx' as talloc owner.
+ */
+ static ir_call *get_error_instruction(void *ctx);
+
+ /**
+ * Get an iterator for the set of acutal parameters
+ */
+ exec_list_iterator iterator()
+ {
+ return actual_parameters.iterator();
+ }
+
+ /**
+ * Get the name of the function being called.
+ */
+ const char *callee_name() const
+ {
+ return callee->function_name();
+ }
+
+ const ir_function_signature *get_callee()
+ {
+ return callee;
+ }
+
+ /**
+ * Generates an inline version of the function before @ir,
+ * returning the return value of the function.
+ */
+ ir_rvalue *generate_inline(ir_instruction *ir);
+
+private:
+ ir_call()
+ : callee(NULL)
+ {
+ /* empty */
+ }
+
+ const ir_function_signature *callee;
+
+ /* List of ir_rvalue of paramaters passed in this call. */
+ exec_list actual_parameters;
+};
+
+
+/**
+ * \name Jump-like IR instructions.
+ *
+ * These include \c break, \c continue, \c return, and \c discard.
+ */
+/*@{*/
+class ir_jump : public ir_instruction {
+protected:
+ ir_jump()
+ {
+ /* empty */
+ }
+};
+
+class ir_return : public ir_jump {
+public:
+ ir_return()
+ : value(NULL)
+ {
+ /* empty */
+ }
+
+ ir_return(ir_rvalue *value)
+ : value(value)
+ {
+ /* empty */
+ }
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ virtual ir_return *as_return()
+ {
+ return this;
+ }
+
+ ir_rvalue *get_value() const
+ {
+ return value;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ ir_rvalue *value;
+};
+
+
+/**
+ * Jump instructions used inside loops
+ *
+ * These include \c break and \c continue. The \c break within a loop is
+ * different from the \c break within a switch-statement.
+ *
+ * \sa ir_switch_jump
+ */
+class ir_loop_jump : public ir_jump {
+public:
+ enum jump_mode {
+ jump_break,
+ jump_continue
+ };
+
+ ir_loop_jump(jump_mode mode)
+ {
+ this->mode = mode;
+ this->loop = loop;
+ }
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ bool is_break() const
+ {
+ return mode == jump_break;
+ }
+
+ bool is_continue() const
+ {
+ return mode == jump_continue;
+ }
+
+ /** Mode selector for the jump instruction. */
+ enum jump_mode mode;
+private:
+ /** Loop containing this break instruction. */
+ ir_loop *loop;
+};
+/*@}*/
+
+
+/**
+ * Texture sampling opcodes used in ir_texture
+ */
+enum ir_texture_opcode {
+ ir_tex, /* Regular texture look-up */
+ ir_txb, /* Texture look-up with LOD bias */
+ ir_txl, /* Texture look-up with explicit LOD */
+ ir_txd, /* Texture look-up with partial derivatvies */
+ ir_txf /* Texel fetch with explicit LOD */
+};
+
+
+/**
+ * IR instruction to sample a texture
+ *
+ * The specific form of the IR instruction depends on the \c mode value
+ * selected from \c ir_texture_opcodes. In the printed IR, these will
+ * appear as:
+ *
+ * Texel offset
+ * | Projection divisor
+ * | | Shadow comparitor
+ * | | |
+ * v v v
+ * (tex (sampler) (coordinate) (0 0 0) (1) ( ))
+ * (txb (sampler) (coordinate) (0 0 0) (1) ( ) (bias))
+ * (txl (sampler) (coordinate) (0 0 0) (1) ( ) (lod))
+ * (txd (sampler) (coordinate) (0 0 0) (1) ( ) (dPdx dPdy))
+ * (txf (sampler) (coordinate) (0 0 0) (lod))
+ */
+class ir_texture : public ir_rvalue {
+public:
+ ir_texture(enum ir_texture_opcode op)
+ : op(op), projector(NULL), shadow_comparitor(NULL)
+ {
+ /* empty */
+ }
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ /**
+ * Return a string representing the ir_texture_opcode.
+ */
+ const char *opcode_string();
+
+ /** Set the sampler and infer the type. */
+ void set_sampler(ir_dereference *sampler);
+
+ /**
+ * Do a reverse-lookup to translate a string into an ir_texture_opcode.
+ */
+ static ir_texture_opcode get_opcode(const char *);
+
+ enum ir_texture_opcode op;
+
+ /** Sampler to use for the texture access. */
+ ir_dereference *sampler;
+
+ /** Texture coordinate to sample */
+ ir_rvalue *coordinate;
+
+ /**
+ * Value used for projective divide.
+ *
+ * If there is no projective divide (the common case), this will be
+ * \c NULL. Optimization passes should check for this to point to a constant
+ * of 1.0 and replace that with \c NULL.
+ */
+ ir_rvalue *projector;
+
+ /**
+ * Coordinate used for comparison on shadow look-ups.
+ *
+ * If there is no shadow comparison, this will be \c NULL. For the
+ * \c ir_txf opcode, this *must* be \c NULL.
+ */
+ ir_rvalue *shadow_comparitor;
+
+ /** Explicit texel offsets. */
+ signed char offsets[3];
+
+ union {
+ ir_rvalue *lod; /**< Floating point LOD */
+ ir_rvalue *bias; /**< Floating point LOD bias */
+ struct {
+ ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */
+ ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */
+ } grad;
+ } lod_info;
+};
+
+
+struct ir_swizzle_mask {
+ unsigned x:2;
+ unsigned y:2;
+ unsigned z:2;
+ unsigned w:2;
+
+ /**
+ * Number of components in the swizzle.
+ */
+ unsigned num_components:3;
+
+ /**
+ * Does the swizzle contain duplicate components?
+ *
+ * L-value swizzles cannot contain duplicate components.
+ */
+ unsigned has_duplicates:1;
+};
+
+
+class ir_swizzle : public ir_rvalue {
+public:
+ ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
+ unsigned count);
+ ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ virtual ir_swizzle *as_swizzle()
+ {
+ return this;
+ }
+
+ /**
+ * Construct an ir_swizzle from the textual representation. Can fail.
+ */
+ static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length);
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ bool is_lvalue()
+ {
+ return val->is_lvalue() && !mask.has_duplicates;
+ }
+
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced();
+
+ ir_rvalue *val;
+ ir_swizzle_mask mask;
+};
+
+
+class ir_dereference : public ir_rvalue {
+public:
+ virtual ir_dereference *as_dereference()
+ {
+ return this;
+ }
+
+ bool is_lvalue();
+
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced() = 0;
+};
+
+
+class ir_dereference_variable : public ir_dereference {
+public:
+ ir_dereference_variable(ir_variable *var);
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced()
+ {
+ return this->var;
+ }
+
+ virtual ir_variable *whole_variable_referenced()
+ {
+ /* ir_dereference_variable objects always dereference the entire
+ * variable. However, if this dereference is dereferenced by anything
+ * else, the complete deferefernce chain is not a whole-variable
+ * dereference. This method should only be called on the top most
+ * ir_rvalue in a dereference chain.
+ */
+ return this->var;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ /**
+ * Object being dereferenced.
+ */
+ ir_variable *var;
+};
+
+
+class ir_dereference_array : public ir_dereference {
+public:
+ ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index);
+
+ ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ virtual ir_dereference_array *as_dereference_array()
+ {
+ return this;
+ }
+
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced()
+ {
+ return this->array->variable_referenced();
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ ir_rvalue *array;
+ ir_rvalue *array_index;
+
+private:
+ void set_array(ir_rvalue *value);
+};
+
+
+class ir_dereference_record : public ir_dereference {
+public:
+ ir_dereference_record(ir_rvalue *value, const char *field);
+
+ ir_dereference_record(ir_variable *var, const char *field);
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced()
+ {
+ return this->record->variable_referenced();
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ ir_rvalue *record;
+ const char *field;
+};
+
+
+/**
+ * Data stored in an ir_constant
+ */
+union ir_constant_data {
+ unsigned u[16];
+ int i[16];
+ float f[16];
+ bool b[16];
+};
+
+
+class ir_constant : public ir_rvalue {
+public:
+ ir_constant(const struct glsl_type *type, const ir_constant_data *data);
+ ir_constant(bool b);
+ ir_constant(unsigned int u);
+ ir_constant(int i);
+ ir_constant(float f);
+
+ /**
+ * Construct an ir_constant from a list of ir_constant values
+ */
+ ir_constant(const struct glsl_type *type, exec_list *values);
+
+ /**
+ * Construct an ir_constant from a scalar component of another ir_constant
+ *
+ * The new \c ir_constant inherits the type of the component from the
+ * source constant.
+ *
+ * \note
+ * In the case of a matrix constant, the new constant is a scalar, \b not
+ * a vector.
+ */
+ ir_constant(const ir_constant *c, unsigned i);
+
+ virtual ir_instruction *clone(struct hash_table *) const;
+
+ virtual ir_constant *as_constant()
+ {
+ return this;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ /**
+ * Get a particular component of a constant as a specific type
+ *
+ * This is useful, for example, to get a value from an integer constant
+ * as a float or bool. This appears frequently when constructors are
+ * called with all constant parameters.
+ */
+ /*@{*/
+ bool get_bool_component(unsigned i) const;
+ float get_float_component(unsigned i) const;
+ int get_int_component(unsigned i) const;
+ unsigned get_uint_component(unsigned i) const;
+ /*@}*/
+
+ ir_constant *get_record_field(const char *name);
+
+ /**
+ * Determine whether a constant has the same value as another constant
+ */
+ bool has_value(const ir_constant *) const;
+
+ /**
+ * Value of the constant.
+ *
+ * The field used to back the values supplied by the constant is determined
+ * by the type associated with the \c ir_instruction. Constants may be
+ * scalars, vectors, or matrices.
+ */
+ union ir_constant_data value;
+
+ exec_list components;
+
+private:
+ /**
+ * Parameterless constructor only used by the clone method
+ */
+ ir_constant(void);
+};
+
+void
+visit_exec_list(exec_list *list, ir_visitor *visitor);
+
+void validate_ir_tree(exec_list *instructions);
+
+extern void
+_mesa_glsl_initialize_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+extern void
+_mesa_glsl_initialize_functions(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+#endif /* IR_H */
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_basic_block.cpp
+ *
+ * Basic block analysis of instruction streams.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_basic_block.h"
+#include "glsl_types.h"
+
+class ir_has_call_visitor : public ir_hierarchical_visitor {
+public:
+ ir_has_call_visitor()
+ {
+ has_call = false;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_call *ir)
+ {
+ (void) ir;
+ has_call = true;
+ return visit_stop;
+ }
+
+ bool has_call;
+};
+
+/**
+ * Calls a user function for every basic block in the instruction stream.
+ *
+ * Basic block analysis is pretty easy in our IR thanks to the lack of
+ * unstructured control flow. We've got:
+ *
+ * ir_loop (for () {}, while () {}, do {} while ())
+ * ir_loop_jump (
+ * ir_if () {}
+ * ir_return
+ * ir_call()
+ *
+ * Note that the basic blocks returned by this don't encompass all
+ * operations performed by the program -- for example, if conditions
+ * don't get returned, nor do the assignments that will be generated
+ * for ir_call parameters.
+ */
+void call_for_basic_blocks(exec_list *instructions,
+ void (*callback)(ir_instruction *first,
+ ir_instruction *last,
+ void *data),
+ void *data)
+{
+ ir_instruction *leader = NULL;
+ ir_instruction *last = NULL;
+
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_if *ir_if;
+ ir_loop *ir_loop;
+ ir_function *ir_function;
+
+ if (!leader)
+ leader = ir;
+
+ if ((ir_if = ir->as_if())) {
+ callback(leader, ir, data);
+ leader = NULL;
+
+ call_for_basic_blocks(&ir_if->then_instructions, callback, data);
+ call_for_basic_blocks(&ir_if->else_instructions, callback, data);
+ } else if ((ir_loop = ir->as_loop())) {
+ callback(leader, ir, data);
+ leader = NULL;
+ call_for_basic_blocks(&ir_loop->body_instructions, callback, data);
+ } else if (ir->as_return() || ir->as_call()) {
+ callback(leader, ir, data);
+ leader = NULL;
+ } else if ((ir_function = ir->as_function())) {
+ /* A function definition doesn't interrupt our basic block
+ * since execution doesn't go into it. We should process the
+ * bodies of its signatures for BBs, though.
+ *
+ * Note that we miss an opportunity for producing more
+ * maximal BBs between the instructions that precede main()
+ * and the body of main(). Perhaps those instructions ought
+ * to live inside of main().
+ */
+ foreach_iter(exec_list_iterator, fun_iter, *ir_function) {
+ ir_function_signature *ir_sig;
+
+ ir_sig = (ir_function_signature *)fun_iter.get();
+
+ call_for_basic_blocks(&ir_sig->body, callback, data);
+ }
+ } else if (ir->as_assignment()) {
+ ir_has_call_visitor v;
+
+ /* If there's a call in the expression tree being assigned,
+ * then that ends the BB too.
+ *
+ * The assumption is that any consumer of the basic block
+ * walker is fine with the fact that the call is somewhere in
+ * the tree even if portions of the tree may be evaluated
+ * after the call.
+ *
+ * A consumer that has an issue with this could not process
+ * the last instruction of the basic block. If doing so,
+ * expression flattener may be useful before using the basic
+ * block finder to get more maximal basic blocks out.
+ */
+ ir->accept(&v);
+ if (v.has_call) {
+ callback(leader, ir, data);
+ leader = NULL;
+ }
+ }
+ last = ir;
+ }
+ if (leader) {
+ callback(leader, last, data);
+ }
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+void call_for_basic_blocks(exec_list *instructions,
+ void (*callback)(ir_instruction *first,
+ ir_instruction *last,
+ void *data),
+ void *data);
--- /dev/null
+/*
+ * 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 <string.h>
+#include "ir.h"
+#include "glsl_types.h"
+#include "hash_table.h"
+
+/**
+ * Duplicate an IR variable
+ *
+ * \note
+ * This will probably be made \c virtual and moved to the base class
+ * eventually.
+ */
+ir_instruction *
+ir_variable::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ ir_variable *var = new(ctx) ir_variable(type, name);
+
+ var->max_array_access = this->max_array_access;
+ var->read_only = this->read_only;
+ var->centroid = this->centroid;
+ var->invariant = this->invariant;
+ var->mode = this->mode;
+ var->interpolation = this->interpolation;
+
+ if (ht) {
+ hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this));
+ }
+
+ return var;
+}
+
+ir_instruction *
+ir_swizzle::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask);
+}
+
+ir_instruction *
+ir_return::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ ir_rvalue *new_value = NULL;
+
+ if (this->value)
+ new_value = (ir_rvalue *)this->value->clone(ht);
+
+ return new(ctx) ir_return(new_value);
+}
+
+ir_instruction *
+ir_loop_jump::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ (void)ht;
+
+ return new(ctx) ir_loop_jump(this->mode);
+}
+
+ir_instruction *
+ir_if::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ ir_if *new_if = new(ctx) ir_if((ir_rvalue *)this->condition->clone(ht));
+
+ foreach_iter(exec_list_iterator, iter, this->then_instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ new_if->then_instructions.push_tail(ir->clone(ht));
+ }
+
+ foreach_iter(exec_list_iterator, iter, this->else_instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ new_if->else_instructions.push_tail(ir->clone(ht));
+ }
+
+ return new_if;
+}
+
+ir_instruction *
+ir_loop::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ ir_loop *new_loop = new(ctx) ir_loop();
+
+ if (this->from)
+ new_loop->from = (ir_rvalue *)this->from->clone(ht);
+ if (this->to)
+ new_loop->to = (ir_rvalue *)this->to->clone(ht);
+ if (this->increment)
+ new_loop->increment = (ir_rvalue *)this->increment->clone(ht);
+ new_loop->counter = counter;
+
+ foreach_iter(exec_list_iterator, iter, this->body_instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ new_loop->body_instructions.push_tail(ir->clone(ht));
+ }
+
+ return new_loop;
+}
+
+ir_instruction *
+ir_call::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ exec_list new_parameters;
+
+ foreach_iter(exec_list_iterator, iter, this->actual_parameters) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ new_parameters.push_tail(ir->clone(ht));
+ }
+
+ return new(ctx) ir_call(this->callee, &new_parameters);
+}
+
+ir_instruction *
+ir_expression::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ ir_rvalue *op[2] = {NULL, NULL};
+ unsigned int i;
+
+ for (i = 0; i < get_num_operands(); i++) {
+ op[i] = (ir_rvalue *)this->operands[i]->clone(ht);
+ }
+
+ return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]);
+}
+
+ir_instruction *
+ir_dereference_variable::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ ir_variable *new_var;
+
+ if (ht) {
+ new_var = (ir_variable *)hash_table_find(ht, this->var);
+ if (!new_var)
+ new_var = this->var;
+ } else {
+ new_var = this->var;
+ }
+
+ return new(ctx) ir_dereference_variable(new_var);
+}
+
+ir_instruction *
+ir_dereference_array::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_dereference_array((ir_rvalue *)this->array->clone(ht),
+ (ir_rvalue *)this->array_index->clone(ht));
+}
+
+ir_instruction *
+ir_dereference_record::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_dereference_record((ir_rvalue *)this->record->clone(ht),
+ this->field);
+}
+
+ir_instruction *
+ir_texture::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ ir_texture *new_tex = new(ctx) ir_texture(this->op);
+
+ new_tex->sampler = (ir_dereference *)this->sampler->clone(ht);
+ new_tex->coordinate = (ir_rvalue *)this->coordinate->clone(ht);
+ if (this->projector)
+ new_tex->projector = (ir_rvalue *)this->projector->clone(ht);
+ if (this->shadow_comparitor) {
+ new_tex->shadow_comparitor =
+ (ir_rvalue *)this->shadow_comparitor->clone(ht);
+ }
+
+ for (int i = 0; i < 3; i++)
+ new_tex->offsets[i] = this->offsets[i];
+
+ switch (this->op) {
+ case ir_tex:
+ break;
+ case ir_txb:
+ new_tex->lod_info.bias = (ir_rvalue *)this->lod_info.bias->clone(ht);
+ break;
+ case ir_txl:
+ case ir_txf:
+ new_tex->lod_info.lod = (ir_rvalue *)this->lod_info.lod->clone(ht);
+ break;
+ case ir_txd:
+ new_tex->lod_info.grad.dPdx =
+ (ir_rvalue *)this->lod_info.grad.dPdx->clone(ht);
+ new_tex->lod_info.grad.dPdy =
+ (ir_rvalue *)this->lod_info.grad.dPdy->clone(ht);
+ break;
+ }
+
+ return new_tex;
+}
+
+ir_instruction *
+ir_assignment::clone(struct hash_table *ht) const
+{
+ ir_rvalue *new_condition = NULL;
+
+ if (this->condition)
+ new_condition = (ir_rvalue *)this->condition->clone(ht);
+
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_assignment((ir_rvalue *)this->lhs->clone(ht),
+ (ir_rvalue *)this->rhs->clone(ht),
+ new_condition);
+}
+
+ir_instruction *
+ir_function::clone(struct hash_table *ht) const
+{
+ (void)ht;
+ /* FINISHME */
+ abort();
+}
+
+ir_instruction *
+ir_function_signature::clone(struct hash_table *ht) const
+{
+ (void)ht;
+ /* FINISHME */
+ abort();
+}
+
+ir_instruction *
+ir_constant::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ (void)ht;
+
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ return new(ctx) ir_constant(this->type, &this->value);
+
+ case GLSL_TYPE_STRUCT: {
+ ir_constant *c = new(ctx) ir_constant;
+
+ c->type = this->type;
+ for (exec_node *node = this->components.head
+ ; !node->is_tail_sentinal()
+ ; node = node->next) {
+ ir_constant *const orig = (ir_constant *) node;
+
+ c->components.push_tail(orig->clone(NULL));
+ }
+
+ return c;
+ }
+
+ default:
+ assert(!"Should not get here."); break;
+ return NULL;
+ }
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_constant_expression.cpp
+ * Evaluate and process constant valued expressions
+ *
+ * In GLSL, constant valued expressions are used in several places. These
+ * must be processed and evaluated very early in the compilation process.
+ *
+ * * Sizes of arrays
+ * * Initializers for uniforms
+ * * Initializers for \c const variables
+ */
+
+#include <math.h>
+#include "ir.h"
+#include "ir_visitor.h"
+#include "glsl_types.h"
+
+/**
+ * Visitor class for evaluating constant expressions
+ */
+class ir_constant_visitor : public ir_visitor {
+public:
+ ir_constant_visitor()
+ : value(NULL)
+ {
+ /* empty */
+ }
+
+ virtual ~ir_constant_visitor()
+ {
+ /* empty */
+ }
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(ir_variable *);
+ virtual void visit(ir_function_signature *);
+ virtual void visit(ir_function *);
+ virtual void visit(ir_expression *);
+ virtual void visit(ir_texture *);
+ virtual void visit(ir_swizzle *);
+ virtual void visit(ir_dereference_variable *);
+ virtual void visit(ir_dereference_array *);
+ virtual void visit(ir_dereference_record *);
+ virtual void visit(ir_assignment *);
+ virtual void visit(ir_constant *);
+ virtual void visit(ir_call *);
+ virtual void visit(ir_return *);
+ virtual void visit(ir_if *);
+ virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
+ /*@}*/
+
+ /**
+ * Value of the constant expression.
+ *
+ * \note
+ * This field will be \c NULL if the expression is not constant valued.
+ */
+ /* FINIHSME: This cannot hold values for constant arrays or structures. */
+ ir_constant *value;
+};
+
+
+ir_constant *
+ir_instruction::constant_expression_value()
+{
+ ir_constant_visitor visitor;
+
+ this->accept(& visitor);
+ return visitor.value;
+}
+
+
+void
+ir_constant_visitor::visit(ir_variable *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_function_signature *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_function *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+void
+ir_constant_visitor::visit(ir_expression *ir)
+{
+ value = NULL;
+ ir_constant *op[2];
+ unsigned int operand, c;
+ ir_constant_data data;
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ op[operand] = ir->operands[operand]->constant_expression_value();
+ if (!op[operand])
+ return;
+ }
+
+ switch (ir->operation) {
+ case ir_unop_logic_not:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (c = 0; c < ir->operands[0]->type->components(); c++)
+ data.b[c] = !op[0]->value.b[c];
+ break;
+
+ case ir_unop_f2i:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.i[c] = op[0]->value.f[c];
+ }
+ break;
+ case ir_unop_i2f:
+ assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
+ op[0]->type->base_type == GLSL_TYPE_INT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ if (op[0]->type->base_type == GLSL_TYPE_INT)
+ data.f[c] = op[0]->value.i[c];
+ else
+ data.f[c] = op[0]->value.u[c];
+ }
+ break;
+ case ir_unop_b2f:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
+ }
+ break;
+ case ir_unop_f2b:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.b[c] = bool(op[0]->value.f[c]);
+ }
+ break;
+ case ir_unop_b2i:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.u[c] = op[0]->value.b[c] ? 1 : 0;
+ }
+ break;
+ case ir_unop_i2b:
+ assert(op[0]->type->is_integer());
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.b[c] = bool(op[0]->value.u[c]);
+ }
+ break;
+
+ case ir_unop_neg:
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = -op[0]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = -op[0]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = -op[0]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_unop_abs:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c];
+ if (data.i[c] < 0)
+ data.i[c] = -data.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = fabs(op[0]->value.f[c]);
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_unop_rcp:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->type->base_type) {
+ case GLSL_TYPE_UINT:
+ if (op[0]->value.u[c] != 0.0)
+ data.u[c] = 1 / op[0]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ if (op[0]->value.i[c] != 0.0)
+ data.i[c] = 1 / op[0]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ if (op[0]->value.f[c] != 0.0)
+ data.f[c] = 1.0 / op[0]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_unop_rsq:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_sqrt:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.f[c] = sqrtf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_exp:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.f[c] = expf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_log:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.f[c] = logf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_dFdx:
+ case ir_unop_dFdy:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ data.f[c] = 0.0;
+ }
+ break;
+
+ case ir_binop_add:
+ if (ir->operands[0]->type == ir->operands[1]->type) {
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c] + op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c] + op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c] + op[1]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ } else
+ /* FINISHME: Support operations with non-equal types. */
+ return;
+
+ break;
+ case ir_binop_sub:
+ if (ir->operands[0]->type == ir->operands[1]->type) {
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c] - op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c] - op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c] - op[1]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ } else
+ /* FINISHME: Support operations with non-equal types. */
+ return;
+
+ break;
+ case ir_binop_mul:
+ if (ir->operands[0]->type == ir->operands[1]->type &&
+ !ir->operands[0]->type->is_matrix()) {
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ } else
+ /* FINISHME: Support operations with non-equal types. */
+ return;
+
+ break;
+ case ir_binop_div:
+ if (ir->operands[0]->type == ir->operands[1]->type) {
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c] / op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c] / op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c] / op[1]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ } else
+ /* FINISHME: Support operations with non-equal types. */
+ return;
+
+ break;
+ case ir_binop_logic_and:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (c = 0; c < ir->operands[0]->type->components(); c++)
+ data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
+ break;
+ case ir_binop_logic_xor:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (c = 0; c < ir->operands[0]->type->components(); c++)
+ data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
+ break;
+ case ir_binop_logic_or:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (c = 0; c < ir->operands[0]->type->components(); c++)
+ data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
+ break;
+
+ case ir_binop_less:
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
+ break;
+ default:
+ assert(0);
+ }
+ break;
+ case ir_binop_greater:
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
+ break;
+ default:
+ assert(0);
+ }
+ break;
+ case ir_binop_lequal:
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
+ break;
+ default:
+ assert(0);
+ }
+ break;
+ case ir_binop_gequal:
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
+ break;
+ default:
+ assert(0);
+ }
+ break;
+
+ case ir_binop_equal:
+ data.b[0] = true;
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
+ break;
+ case GLSL_TYPE_BOOL:
+ data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+ case ir_binop_nequal:
+ data.b[0] = false;
+ for (c = 0; c < ir->operands[0]->type->components(); c++) {
+ switch (ir->operands[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
+ break;
+ case GLSL_TYPE_BOOL:
+ data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ default:
+ /* FINISHME: Should handle all expression types. */
+ return;
+ }
+
+ void *ctx = talloc_parent(ir);
+ this->value = new(ctx) ir_constant(ir->type, &data);
+}
+
+
+void
+ir_constant_visitor::visit(ir_texture *ir)
+{
+ // FINISHME: Do stuff with texture lookups
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_swizzle *ir)
+{
+ ir_constant *v = ir->val->constant_expression_value();
+
+ this->value = NULL;
+
+ if (v != NULL) {
+ ir_constant_data data;
+
+ const unsigned swiz_idx[4] = {
+ ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
+ };
+
+ for (unsigned i = 0; i < ir->mask.num_components; i++) {
+ switch (v->type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
+ case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
+ case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
+ default: assert(!"Should not get here."); break;
+ }
+ }
+
+ void *ctx = talloc_parent(ir);
+ this->value = new(ctx) ir_constant(ir->type, &data);
+ }
+}
+
+
+void
+ir_constant_visitor::visit(ir_dereference_variable *ir)
+{
+ value = NULL;
+
+ ir_variable *var = ir->variable_referenced();
+ if (var && var->constant_value)
+ value = (ir_constant *)var->constant_value->clone(NULL);
+}
+
+
+void
+ir_constant_visitor::visit(ir_dereference_array *ir)
+{
+ void *ctx = talloc_parent(ir);
+ ir_constant *array = ir->array->constant_expression_value();
+ ir_constant *idx = ir->array_index->constant_expression_value();
+
+ this->value = NULL;
+
+ if ((array != NULL) && (idx != NULL)) {
+ if (array->type->is_matrix()) {
+ /* Array access of a matrix results in a vector.
+ */
+ const unsigned column = idx->value.u[0];
+
+ const glsl_type *const column_type = array->type->column_type();
+
+ /* Offset in the constant matrix to the first element of the column
+ * to be extracted.
+ */
+ const unsigned mat_idx = column * column_type->vector_elements;
+
+ ir_constant_data data;
+
+ switch (column_type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ for (unsigned i = 0; i < column_type->vector_elements; i++)
+ data.u[i] = array->value.u[mat_idx + i];
+
+ break;
+
+ case GLSL_TYPE_FLOAT:
+ for (unsigned i = 0; i < column_type->vector_elements; i++)
+ data.f[i] = array->value.f[mat_idx + i];
+
+ break;
+
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+
+ this->value = new(ctx) ir_constant(column_type, &data);
+ } else if (array->type->is_vector()) {
+ const unsigned component = idx->value.u[0];
+
+ this->value = new(ctx) ir_constant(array, component);
+ } else {
+ /* FINISHME: Handle access of constant arrays. */
+ }
+ }
+}
+
+
+void
+ir_constant_visitor::visit(ir_dereference_record *ir)
+{
+ ir_constant *v = ir->record->constant_expression_value();
+
+ this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_assignment *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_constant *ir)
+{
+ value = ir;
+}
+
+
+void
+ir_constant_visitor::visit(ir_call *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_return *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_if *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_loop *ir)
+{
+ (void) ir;
+ value = NULL;
+}
+
+
+void
+ir_constant_visitor::visit(ir_loop_jump *ir)
+{
+ (void) ir;
+ value = NULL;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_constant_folding.cpp
+ * Replace constant-valued expressions with references to constant values.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+/**
+ * Visitor class for replacing expressions with ir_constant values.
+ */
+
+class ir_constant_folding_visitor : public ir_visitor {
+public:
+ ir_constant_folding_visitor()
+ {
+ /* empty */
+ }
+
+ virtual ~ir_constant_folding_visitor()
+ {
+ /* empty */
+ }
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(ir_variable *);
+ virtual void visit(ir_function_signature *);
+ virtual void visit(ir_function *);
+ virtual void visit(ir_expression *);
+ virtual void visit(ir_texture *);
+ virtual void visit(ir_swizzle *);
+ virtual void visit(ir_dereference_variable *);
+ virtual void visit(ir_dereference_array *);
+ virtual void visit(ir_dereference_record *);
+ virtual void visit(ir_assignment *);
+ virtual void visit(ir_constant *);
+ virtual void visit(ir_call *);
+ virtual void visit(ir_return *);
+ virtual void visit(ir_if *);
+ virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
+ /*@}*/
+};
+
+void
+ir_constant_folding_visitor::visit(ir_variable *ir)
+{
+ (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_function_signature *ir)
+{
+ visit_exec_list(&ir->body, this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_function *ir)
+{
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_function_signature *const sig = (ir_function_signature *) iter.get();
+ sig->accept(this);
+ }
+}
+
+void
+ir_constant_folding_visitor::visit(ir_expression *ir)
+{
+ ir_constant *op[2];
+ unsigned int operand;
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ op[operand] = ir->operands[operand]->constant_expression_value();
+ if (op[operand]) {
+ ir->operands[operand] = op[operand];
+ } else {
+ ir->operands[operand]->accept(this);
+ }
+ }
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_texture *ir)
+{
+ // FINISHME: Do stuff with texture lookups
+ (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_swizzle *ir)
+{
+ ir->val->accept(this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_dereference_variable *ir)
+{
+ (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_dereference_array *ir)
+{
+ ir_constant *const_val =
+ ir->array_index->constant_expression_value();
+
+ if (const_val)
+ ir->array_index = const_val;
+ else
+ ir->array_index->accept(this);
+
+ ir->array->accept(this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_dereference_record *ir)
+{
+ ir->record->accept(this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_assignment *ir)
+{
+ ir_constant *const_val = ir->rhs->constant_expression_value();
+ if (const_val)
+ ir->rhs = const_val;
+ else
+ ir->rhs->accept(this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_constant *ir)
+{
+ (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_call *ir)
+{
+ (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_return *ir)
+{
+ (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_if *ir)
+{
+ ir_constant *const_val = ir->condition->constant_expression_value();
+ if (const_val)
+ ir->condition = const_val;
+ else
+ ir->condition->accept(this);
+
+ visit_exec_list(&ir->then_instructions, this);
+ visit_exec_list(&ir->else_instructions, this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_loop *ir)
+{
+ (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_loop_jump *ir)
+{
+ (void) ir;
+}
+
+bool
+do_constant_folding(exec_list *instructions)
+{
+ ir_constant_folding_visitor constant_folding;
+
+ visit_exec_list(instructions, &constant_folding);
+
+ /* FINISHME: Return real progress. */
+ return false;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_constant_variable.cpp
+ *
+ * Marks variables assigned a single constant value over the course
+ * of the program as constant.
+ *
+ * The goal here is to trigger further constant folding and then dead
+ * code elimination. This is common with vector/matrix constructors
+ * and calls to builtin functions.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+struct assignment_entry {
+ exec_node link;
+ int assignment_count;
+ ir_variable *var;
+ ir_constant *constval;
+};
+
+class ir_constant_variable_visitor : public ir_hierarchical_visitor {
+public:
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+
+ exec_list list;
+};
+
+static struct assignment_entry *
+get_assignment_entry(ir_variable *var, exec_list *list)
+{
+ struct assignment_entry *entry;
+
+ foreach_list_typed(struct assignment_entry, entry, link, list) {
+ if (entry->var == var)
+ return entry;
+ }
+
+ entry = (struct assignment_entry *)calloc(1, sizeof(*entry));
+ entry->var = var;
+ list->push_head(&entry->link);
+ return entry;
+}
+
+ir_visitor_status
+ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
+{
+ ir_constant *constval;
+ struct assignment_entry *entry;
+
+ entry = get_assignment_entry(ir->lhs->variable_referenced(), &this->list);
+ assert(entry);
+ entry->assignment_count++;
+
+ /* If it's already constant, don't do the work. */
+ if (entry->var->constant_value)
+ return visit_continue;
+
+ /* OK, now find if we actually have all the right conditions for
+ * this to be a constant value assigned to the var.
+ */
+ if (ir->condition) {
+ constval = ir->condition->constant_expression_value();
+ if (!constval || !constval->value.b[0])
+ return visit_continue;
+ }
+
+ ir_variable *var = ir->lhs->whole_variable_referenced();
+ if (!var)
+ return visit_continue;
+
+ constval = ir->rhs->constant_expression_value();
+ if (!constval)
+ return visit_continue;
+
+ /* Mark this entry as having a constant assignment (if the
+ * assignment count doesn't go >1). do_constant_variable will fix
+ * up the variable with the constant value later.
+ */
+ entry->constval = constval;
+
+ return visit_continue;
+}
+
+/**
+ * Does a copy propagation pass on the code present in the instruction stream.
+ */
+bool
+do_constant_variable(exec_list *instructions)
+{
+ bool progress = false;
+ ir_constant_variable_visitor v;
+
+ v.run(instructions);
+
+ while (!v.list.is_empty()) {
+
+ struct assignment_entry *entry;
+ entry = exec_node_data(struct assignment_entry, v.list.head, link);
+
+ if (entry->assignment_count == 1 && entry->constval) {
+ entry->var->constant_value = entry->constval;
+ progress = true;
+ }
+ entry->link.remove();
+ free(entry);
+ }
+
+ return progress;
+}
+
+bool
+do_constant_variable_unlinked(exec_list *instructions)
+{
+ bool progress = false;
+
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_function *f = ir->as_function();
+ if (f) {
+ foreach_iter(exec_list_iterator, sigiter, *f) {
+ ir_function_signature *sig =
+ (ir_function_signature *) sigiter.get();
+ if (do_constant_variable(&sig->body))
+ progress = true;
+ }
+ }
+ }
+
+ return progress;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_copy_propagation.cpp
+ *
+ * Moves usage of recently-copied variables to the previous copy of
+ * the variable within basic blocks.
+ *
+ * This should reduce the number of MOV instructions in the generated
+ * programs unless copy propagation is also done on the LIR, and may
+ * help anyway by triggering other optimizations that live in the HIR.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_basic_block.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+class acp_entry : public exec_node
+{
+public:
+ acp_entry(ir_variable *lhs, ir_variable *rhs)
+ {
+ assert(lhs);
+ assert(rhs);
+ this->lhs = lhs;
+ this->rhs = rhs;
+ }
+
+ ir_variable *lhs;
+ ir_variable *rhs;
+};
+
+class ir_copy_propagation_visitor : public ir_hierarchical_visitor {
+public:
+ ir_copy_propagation_visitor(exec_list *acp)
+ {
+ progress = false;
+ in_lhs = false;
+ this->acp = acp;
+ }
+
+ virtual ir_visitor_status visit(class ir_dereference_variable *);
+ virtual ir_visitor_status visit_enter(class ir_loop *);
+ virtual ir_visitor_status visit_enter(class ir_function_signature *);
+ virtual ir_visitor_status visit_enter(class ir_function *);
+ virtual ir_visitor_status visit_enter(class ir_assignment *);
+ virtual ir_visitor_status visit_enter(class ir_call *);
+ virtual ir_visitor_status visit_enter(class ir_if *);
+
+ /** List of acp_entry */
+ exec_list *acp;
+ bool progress;
+
+ /** Currently in the LHS of an assignment? */
+ bool in_lhs;
+};
+
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_loop *ir)
+{
+ (void)ir;
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_function_signature *ir)
+{
+ (void)ir;
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_assignment *ir)
+{
+ (void) ir;
+ this->in_lhs = true;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_function *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+/**
+ * Replaces dereferences of ACP RHS variables with ACP LHS variables.
+ *
+ * This is where the actual copy propagation occurs. Note that the
+ * rewriting of ir_dereference means that the ir_dereference instance
+ * must not be shared by multiple IR operations!
+ */
+ir_visitor_status
+ir_copy_propagation_visitor::visit(ir_dereference_variable *ir)
+{
+ /* Ignores the LHS. Don't want to rewrite the LHS to point at some
+ * other storage!
+ */
+ if (this->in_lhs) {
+ this->in_lhs = false;
+ return visit_continue;
+ }
+
+ ir_variable *var = ir->variable_referenced();
+
+ foreach_iter(exec_list_iterator, iter, *this->acp) {
+ acp_entry *entry = (acp_entry *)iter.get();
+
+ if (var == entry->lhs) {
+ ir->var = entry->rhs;
+ this->progress = true;
+ break;
+ }
+ }
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_call *ir)
+{
+ (void)ir;
+
+ /* Note, if we were to do copy propagation to parameters of calls, we'd
+ * have to be careful about out params.
+ */
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_if *ir)
+{
+ ir->condition->accept(this);
+
+ /* Do not traverse into the body of the if-statement since that is a
+ * different basic block.
+ */
+ return visit_continue_with_parent;
+}
+
+static bool
+propagate_copies(ir_instruction *ir, exec_list *acp)
+{
+ ir_copy_propagation_visitor v(acp);
+
+ ir->accept(&v);
+
+ return v.progress;
+}
+
+static void
+kill_invalidated_copies(ir_assignment *ir, exec_list *acp)
+{
+ ir_variable *var = ir->lhs->variable_referenced();
+ assert(var != NULL);
+
+ foreach_iter(exec_list_iterator, iter, *acp) {
+ acp_entry *entry = (acp_entry *)iter.get();
+
+ if (entry->lhs == var || entry->rhs == var) {
+ entry->remove();
+ }
+ }
+}
+
+/**
+ * Adds an entry to the available copy list if it's a plain assignment
+ * of a variable to a variable.
+ */
+static void
+add_copy(ir_assignment *ir, exec_list *acp)
+{
+ void *ctx = talloc_parent(ir);
+ acp_entry *entry;
+
+ if (ir->condition) {
+ ir_constant *condition = ir->condition->as_constant();
+ if (!condition || !condition->value.b[0])
+ return;
+ }
+
+ ir_variable *lhs_var = ir->lhs->whole_variable_referenced();
+ ir_variable *rhs_var = ir->rhs->whole_variable_referenced();
+
+ if ((lhs_var != NULL) && (rhs_var != NULL)) {
+ entry = new(ctx) acp_entry(lhs_var, rhs_var);
+ acp->push_tail(entry);
+ }
+}
+
+static void
+copy_propagation_basic_block(ir_instruction *first,
+ ir_instruction *last,
+ void *data)
+{
+ ir_instruction *ir;
+ /* List of avaialble_copy */
+ exec_list acp;
+ bool *out_progress = (bool *)data;
+ bool progress = false;
+
+ for (ir = first;; ir = (ir_instruction *)ir->next) {
+ ir_assignment *ir_assign = ir->as_assignment();
+
+ progress = propagate_copies(ir, &acp) || progress;
+
+ if (ir_assign) {
+ kill_invalidated_copies(ir_assign, &acp);
+
+ add_copy(ir_assign, &acp);
+ }
+ if (ir == last)
+ break;
+ }
+ *out_progress = progress;
+}
+
+/**
+ * Does a copy propagation pass on the code present in the instruction stream.
+ */
+bool
+do_copy_propagation(exec_list *instructions)
+{
+ bool progress = false;
+
+ call_for_basic_blocks(instructions, copy_propagation_basic_block, &progress);
+
+ return progress;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_dead_code.cpp
+ *
+ * Eliminates dead assignments and variable declarations from the code.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+
+class variable_entry : public exec_node
+{
+public:
+ variable_entry(ir_variable *var)
+ {
+ this->var = var;
+ assign = NULL;
+ referenced_count = 0;
+ assigned_count = 0;
+ declaration = false;
+ }
+
+ ir_variable *var; /* The key: the variable's pointer. */
+ ir_assignment *assign; /* An assignment to the variable, if any */
+
+ /** Number of times the variable is referenced, including assignments. */
+ unsigned referenced_count;
+
+ /** Number of times the variable is assignmened. */
+ unsigned assigned_count;
+
+ bool declaration; /* If the variable had a decl in the instruction stream */
+};
+
+class ir_dead_code_visitor : public ir_hierarchical_visitor {
+public:
+ virtual ir_visitor_status visit(ir_variable *);
+ virtual ir_visitor_status visit(ir_dereference_variable *);
+
+ virtual ir_visitor_status visit_enter(ir_function *);
+ virtual ir_visitor_status visit_leave(ir_assignment *);
+
+ variable_entry *get_variable_entry(ir_variable *var);
+
+ bool (*predicate)(ir_instruction *ir);
+ ir_instruction *base_ir;
+
+ /* List of variable_entry */
+ exec_list variable_list;
+};
+
+
+variable_entry *
+ir_dead_code_visitor::get_variable_entry(ir_variable *var)
+{
+ assert(var);
+ foreach_iter(exec_list_iterator, iter, this->variable_list) {
+ variable_entry *entry = (variable_entry *)iter.get();
+ if (entry->var == var)
+ return entry;
+ }
+
+ void *ctx = talloc_parent(var);
+
+ variable_entry *entry = new(ctx) variable_entry(var);
+ this->variable_list.push_tail(entry);
+ return entry;
+}
+
+
+ir_visitor_status
+ir_dead_code_visitor::visit(ir_variable *ir)
+{
+ variable_entry *entry = this->get_variable_entry(ir);
+ if (entry)
+ entry->declaration = true;
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+ir_dead_code_visitor::visit(ir_dereference_variable *ir)
+{
+ ir_variable *const var = ir->variable_referenced();
+ variable_entry *entry = this->get_variable_entry(var);
+
+ if (entry)
+ entry->referenced_count++;
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+ir_dead_code_visitor::visit_enter(ir_function *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_dead_code_visitor::visit_leave(ir_assignment *ir)
+{
+ variable_entry *entry;
+ entry = this->get_variable_entry(ir->lhs->variable_referenced());
+ if (entry) {
+ entry->assigned_count++;
+ if (entry->assign == NULL)
+ entry->assign = ir;
+ }
+
+ return visit_continue;
+}
+
+
+/**
+ * Do a dead code pass over instructions and everything that instructions
+ * references.
+ *
+ * Note that this will remove assignments to globals, so it is not suitable
+ * for usage on an unlinked instruction stream.
+ */
+bool
+do_dead_code(exec_list *instructions)
+{
+ ir_dead_code_visitor v;
+ bool progress = false;
+
+ v.run(instructions);
+
+ foreach_iter(exec_list_iterator, iter, v.variable_list) {
+ variable_entry *entry = (variable_entry *)iter.get();
+
+ /* Since each assignment is a reference, the refereneced count must be
+ * greater than or equal to the assignment count. If they are equal,
+ * then all of the references are assignments, and the variable is
+ * dead.
+ *
+ * Note that if the variable is neither assigned nor referenced, both
+ * counts will be zero and will be caught by the equality test.
+ */
+ assert(entry->referenced_count >= entry->assigned_count);
+
+ if ((entry->referenced_count > entry->assigned_count)
+ || !entry->declaration)
+ continue;
+
+ if (entry->assign) {
+ /* Remove a single dead assignment to the variable we found.
+ * Don't do so if it's a shader output, though.
+ */
+ if (!entry->var->shader_out) {
+ entry->assign->remove();
+ progress = true;
+ }
+ } else {
+ /* If there are no assignments or references to the variable left,
+ * then we can remove its declaration.
+ */
+ entry->var->remove();
+ progress = true;
+ }
+ }
+ return progress;
+}
+
+/**
+ * Does a dead code pass on the functions present in the instruction stream.
+ *
+ * This is suitable for use while the program is not linked, as it will
+ * ignore variable declarations (and the assignments to them) for variables
+ * with global scope.
+ */
+bool
+do_dead_code_unlinked(exec_list *instructions)
+{
+ bool progress = false;
+
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_function *f = ir->as_function();
+ if (f) {
+ foreach_iter(exec_list_iterator, sigiter, *f) {
+ ir_function_signature *sig =
+ (ir_function_signature *) sigiter.get();
+ if (do_dead_code(&sig->body))
+ progress = true;
+ }
+ }
+ }
+
+ return progress;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_dead_code_local.cpp
+ *
+ * Eliminates local dead assignments from the code.
+ *
+ * This operates on basic blocks, tracking assignments and finding if
+ * they're used before the variable is completely reassigned.
+ *
+ * Compare this to ir_dead_code.cpp, which operates globally looking
+ * for assignments to variables that are never read.
+ */
+
+#include "ir.h"
+#include "ir_basic_block.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+static bool debug = false;
+
+class assignment_entry : public exec_node
+{
+public:
+ assignment_entry(ir_variable *lhs, ir_instruction *ir)
+ {
+ assert(lhs);
+ assert(ir);
+ this->lhs = lhs;
+ this->ir = ir;
+ }
+
+ ir_variable *lhs;
+ ir_instruction *ir;
+};
+
+class kill_for_derefs_visitor : public ir_hierarchical_visitor {
+public:
+ kill_for_derefs_visitor(exec_list *assignments)
+ {
+ this->assignments = assignments;
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ ir_variable *const var = ir->variable_referenced();
+
+ foreach_iter(exec_list_iterator, iter, *this->assignments) {
+ assignment_entry *entry = (assignment_entry *)iter.get();
+
+ if (entry->lhs == var) {
+ if (debug)
+ printf("kill %s\n", entry->lhs->name);
+ entry->remove();
+ }
+ }
+
+ return visit_continue;
+ }
+
+private:
+ exec_list *assignments;
+};
+
+class array_index_visit : public ir_hierarchical_visitor {
+public:
+ array_index_visit(ir_hierarchical_visitor *v)
+ {
+ this->visitor = v;
+ }
+
+ virtual ir_visitor_status visit_enter(class ir_dereference_array *ir)
+ {
+ ir->array_index->accept(visitor);
+ return visit_continue;
+ }
+
+ static void run(ir_instruction *ir, ir_hierarchical_visitor *v)
+ {
+ array_index_visit top_visit(v);
+ ir->accept(& top_visit);
+ }
+
+ ir_hierarchical_visitor *visitor;
+};
+
+
+/**
+ * Adds an entry to the available copy list if it's a plain assignment
+ * of a variable to a variable.
+ */
+static bool
+process_assignment(ir_assignment *ir, exec_list *assignments)
+{
+ void *ctx = talloc_parent(ir);
+ ir_variable *var = NULL;
+ bool progress = false;
+ kill_for_derefs_visitor v(assignments);
+
+ /* Kill assignment entries for things used to produce this assignment. */
+ ir->rhs->accept(&v);
+ if (ir->condition) {
+ ir->condition->accept(&v);
+ }
+
+ /* Kill assignment enties used as array indices.
+ */
+ array_index_visit::run(ir->lhs, &v);
+ var = ir->lhs->variable_referenced();
+ assert(var);
+
+ bool always_assign = true;
+ if (ir->condition) {
+ ir_constant *condition = ir->condition->as_constant();
+ if (!condition || !condition->value.b[0])
+ always_assign = false;
+ }
+
+ /* Now, check if we did a whole-variable assignment. */
+ if (always_assign && (ir->lhs->whole_variable_referenced() != NULL)) {
+ /* We did a whole-variable assignment. So, any instruction in
+ * the assignment list with the same LHS is dead.
+ */
+ if (debug)
+ printf("looking for %s to remove\n", var->name);
+ foreach_iter(exec_list_iterator, iter, *assignments) {
+ assignment_entry *entry = (assignment_entry *)iter.get();
+
+ if (entry->lhs == var) {
+ if (debug)
+ printf("removing %s\n", var->name);
+ entry->ir->remove();
+ entry->remove();
+ progress = true;
+ }
+ }
+ }
+
+ /* Add this instruction to the assignment list. */
+ assignment_entry *entry = new(ctx) assignment_entry(var, ir);
+ assignments->push_tail(entry);
+
+ if (debug) {
+ printf("add %s\n", var->name);
+
+ printf("current entries\n");
+ foreach_iter(exec_list_iterator, iter, *assignments) {
+ assignment_entry *entry = (assignment_entry *)iter.get();
+
+ printf(" %s\n", entry->lhs->name);
+ }
+ }
+
+ return progress;
+}
+
+static void
+dead_code_local_basic_block(ir_instruction *first,
+ ir_instruction *last,
+ void *data)
+{
+ ir_instruction *ir, *ir_next;
+ /* List of avaialble_copy */
+ exec_list assignments;
+ bool *out_progress = (bool *)data;
+ bool progress = false;
+
+ /* Safe looping, since process_assignment */
+ for (ir = first, ir_next = (ir_instruction *)first->next;;
+ ir = ir_next, ir_next = (ir_instruction *)ir->next) {
+ ir_assignment *ir_assign = ir->as_assignment();
+
+ if (debug) {
+ ir->print();
+ printf("\n");
+ }
+
+ if (ir_assign) {
+ progress = process_assignment(ir_assign, &assignments) || progress;
+ } else {
+ kill_for_derefs_visitor kill(&assignments);
+ ir->accept(&kill);
+ }
+
+ if (ir == last)
+ break;
+ }
+ *out_progress = progress;
+}
+
+/**
+ * Does a copy propagation pass on the code present in the instruction stream.
+ */
+bool
+do_dead_code_local(exec_list *instructions)
+{
+ bool progress = false;
+
+ call_for_basic_blocks(instructions, dead_code_local_basic_block, &progress);
+
+ return progress;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_expression_flattening.cpp
+ *
+ * Takes the leaves of expression trees and makes them dereferences of
+ * assignments of the leaves to temporaries, according to a predicate.
+ *
+ * This is used for automatic function inlining, where we want to take
+ * an expression containing a call and move the call out to its own
+ * assignment so that we can inline it at the appropriate place in the
+ * instruction stream.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+
+class ir_expression_flattening_visitor : public ir_hierarchical_visitor {
+public:
+ ir_expression_flattening_visitor(ir_instruction *base_ir,
+ bool (*predicate)(ir_instruction *ir))
+ {
+ this->base_ir = base_ir;
+ this->predicate = predicate;
+ }
+
+ virtual ~ir_expression_flattening_visitor()
+ {
+ /* empty */
+ }
+
+ virtual ir_visitor_status visit_enter(ir_call *);
+ virtual ir_visitor_status visit_enter(ir_return *);
+ virtual ir_visitor_status visit_enter(ir_function_signature *);
+ virtual ir_visitor_status visit_enter(ir_if *);
+ virtual ir_visitor_status visit_enter(ir_loop *);
+ virtual ir_visitor_status visit_leave(ir_expression *);
+ virtual ir_visitor_status visit_leave(ir_swizzle *);
+
+ bool (*predicate)(ir_instruction *ir);
+ ir_instruction *base_ir;
+};
+
+void
+do_expression_flattening(exec_list *instructions,
+ bool (*predicate)(ir_instruction *ir))
+{
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+
+ ir_expression_flattening_visitor v(ir, predicate);
+ ir->accept(&v);
+ }
+}
+
+
+static ir_rvalue *
+operand_to_temp(ir_instruction *base_ir, ir_rvalue *ir)
+{
+ void *ctx = talloc_parent(base_ir);
+ ir_variable *var;
+ ir_assignment *assign;
+
+ var = new(ctx) ir_variable(ir->type, "flattening_tmp");
+ base_ir->insert_before(var);
+
+ assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+ ir,
+ NULL);
+ base_ir->insert_before(assign);
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+ir_visitor_status
+ir_expression_flattening_visitor::visit_enter(ir_function_signature *ir)
+{
+ do_expression_flattening(&ir->body, this->predicate);
+
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_expression_flattening_visitor::visit_enter(ir_loop *ir)
+{
+ do_expression_flattening(&ir->body_instructions, this->predicate);
+
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_expression_flattening_visitor::visit_enter(ir_if *ir)
+{
+ ir->condition->accept(this);
+
+ do_expression_flattening(&ir->then_instructions, this->predicate);
+ do_expression_flattening(&ir->else_instructions, this->predicate);
+
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_expression_flattening_visitor::visit_leave(ir_expression *ir)
+{
+ unsigned int operand;
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ /* If the operand matches the predicate, then we'll assign its
+ * value to a temporary and deref the temporary as the operand.
+ */
+ if (this->predicate(ir->operands[operand])) {
+ ir->operands[operand] = operand_to_temp(base_ir,
+ ir->operands[operand]);
+ }
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_expression_flattening_visitor::visit_leave(ir_swizzle *ir)
+{
+ if (this->predicate(ir->val)) {
+ ir->val = operand_to_temp(this->base_ir, ir->val);
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_expression_flattening_visitor::visit_enter(ir_call *ir)
+{
+ /* FINISHME: Why not process the call parameters? (Same behavior as original
+ * FINISHME: code.)
+ */
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_expression_flattening_visitor::visit_enter(ir_return *ir)
+{
+ /* FINISHME: Why not process the return value? (Same behavior as original
+ * FINISHME: code.)
+ */
+ (void) ir;
+ return visit_continue_with_parent;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+
+/**
+ * \file ir_expression_flattening.h
+ *
+ * Takes the leaves of expression trees and makes them dereferences of
+ * assignments of the leaves to temporaries, according to a predicate.
+ *
+ * This is used for automatic function inlining, where we want to take
+ * an expression containing a call and move the call out to its own
+ * assignment so that we can inline it at the appropriate place in the
+ * instruction stream.
+ */
+
+void do_expression_flattening(exec_list *instructions,
+ bool (*predicate)(ir_instruction *ir));
--- /dev/null
+/*
+ * 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 "ir.h"
+
+int
+type_compare(const glsl_type *a, const glsl_type *b)
+{
+ /* If the types are the same, they trivially match.
+ */
+ if (a == b)
+ return 0;
+
+ switch (a->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_BOOL:
+ /* There is no implicit conversion to or from integer types or bool.
+ */
+ if ((a->is_integer() != b->is_integer())
+ || (a->is_boolean() != b->is_boolean()))
+ return -1;
+
+ /* FALLTHROUGH */
+
+ case GLSL_TYPE_FLOAT:
+ if ((a->vector_elements != b->vector_elements)
+ || (a->matrix_columns != b->matrix_columns))
+ return -1;
+
+ return 1;
+
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_STRUCT:
+ /* Samplers and structures must match exactly.
+ */
+ return -1;
+
+ case GLSL_TYPE_ARRAY:
+ if ((b->base_type != GLSL_TYPE_ARRAY)
+ || (a->length != b->length))
+ return -1;
+
+ /* From GLSL 1.50 spec, page 27 (page 33 of the PDF):
+ * "There are no implicit array or structure conversions."
+ *
+ * If the comparison of the array element types detects that a conversion
+ * would be required, the array types do not match.
+ */
+ return (type_compare(a->fields.array, b->fields.array) == 0) ? 0 : -1;
+
+ case GLSL_TYPE_FUNCTION:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_ERROR:
+ default:
+ /* These are all error conditions. It is invalid for a parameter to
+ * a function to be declared as error, void, or a function.
+ */
+ return -1;
+ }
+
+ /* This point should be unreachable.
+ */
+ assert(0);
+}
+
+
+static int
+parameter_lists_match(exec_list *list_a, exec_list *list_b)
+{
+ exec_list_iterator iter_a = list_a->iterator();
+ exec_list_iterator iter_b = list_b->iterator();
+ int total_score = 0;
+
+ for (/* empty */ ; iter_a.has_next(); iter_a.next(), iter_b.next()) {
+ /* If all of the parameters from the other parameter list have been
+ * exhausted, the lists have different length and, by definition,
+ * do not match.
+ */
+ if (!iter_b.has_next())
+ return -1;
+
+
+ const ir_variable *const param = (ir_variable *) iter_a.get();
+ const ir_instruction *const actual = (ir_instruction *) iter_b.get();
+
+ /* Determine whether or not the types match. If the types are an
+ * exact match, the match score is zero. If the types don't match
+ * but the actual parameter can be coerced to the type of the declared
+ * parameter, the match score is one.
+ */
+ int score;
+ switch ((enum ir_variable_mode)(param->mode)) {
+ case ir_var_auto:
+ case ir_var_uniform:
+ /* These are all error conditions. It is invalid for a parameter to
+ * a function to be declared as auto (not in, out, or inout) or
+ * as uniform.
+ */
+ assert(0);
+ return -1;
+
+ case ir_var_in:
+ score = type_compare(param->type, actual->type);
+ break;
+
+ case ir_var_out:
+ score = type_compare(actual->type, param->type);
+ break;
+
+ case ir_var_inout:
+ /* Since there are no bi-directional automatic conversions (e.g.,
+ * there is int -> float but no float -> int), inout parameters must
+ * be exact matches.
+ */
+ score = (type_compare(actual->type, param->type) == 0) ? 0 : -1;
+ break;
+ }
+
+ if (score < 0)
+ return -1;
+
+ total_score += score;
+ }
+
+ /* If all of the parameters from the other parameter list have been
+ * exhausted, the lists have different length and, by definition, do not
+ * match.
+ */
+ if (iter_b.has_next())
+ return -1;
+
+ return total_score;
+}
+
+
+const ir_function_signature *
+ir_function::matching_signature(exec_list *actual_parameters)
+{
+ ir_function_signature *match = NULL;
+
+ foreach_iter(exec_list_iterator, iter, signatures) {
+ ir_function_signature *const sig =
+ (ir_function_signature *) iter.get();
+
+ const int score = parameter_lists_match(& sig->parameters,
+ actual_parameters);
+
+ if (score == 0)
+ return sig;
+
+ if (score > 0) {
+ if (match != NULL)
+ return NULL;
+
+ match = sig;
+ }
+ }
+
+ return match;
+}
+
+
+static bool
+parameter_lists_match_exact(exec_list *list_a, exec_list *list_b)
+{
+ exec_list_iterator iter_a = list_a->iterator();
+ exec_list_iterator iter_b = list_b->iterator();
+
+ while (iter_a.has_next() && iter_b.has_next()) {
+ ir_variable *a = (ir_variable *)iter_a.get();
+ ir_variable *b = (ir_variable *)iter_b.get();
+
+ /* If the types of the parameters do not match, the parameters lists
+ * are different.
+ */
+ if (a->type != b->type)
+ return false;
+
+ iter_a.next();
+ iter_b.next();
+ }
+
+ /* Unless both lists are exhausted, they differ in length and, by
+ * definition, do not match.
+ */
+ if (iter_a.has_next() != iter_b.has_next())
+ return false;
+
+ return true;
+}
+
+ir_function_signature *
+ir_function::exact_matching_signature(exec_list *actual_parameters)
+{
+ foreach_iter(exec_list_iterator, iter, signatures) {
+ ir_function_signature *const sig =
+ (ir_function_signature *) iter.get();
+
+ if (parameter_lists_match_exact(&sig->parameters, actual_parameters))
+ return sig;
+ }
+ return NULL;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_function_can_inline.cpp
+ *
+ * Determines if we can inline a function call using ir_function_inlining.cpp.
+ *
+ * The primary restriction is that we can't return from the function
+ * other than as the last instruction. We could potentially work
+ * around this for some constructs by flattening control flow and
+ * moving the return to the end, or by using breaks from a do {} while
+ * (0) loop surrounding the function body.
+ */
+
+#include "ir.h"
+
+class ir_function_can_inline_visitor : public ir_hierarchical_visitor {
+public:
+ ir_function_can_inline_visitor()
+ {
+ this->num_returns = 0;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_return *);
+
+ int num_returns;
+};
+
+ir_visitor_status
+ir_function_can_inline_visitor::visit_enter(ir_return *ir)
+{
+ (void) ir;
+ this->num_returns++;
+ return visit_continue;
+}
+
+bool
+can_inline(ir_call *call)
+{
+ ir_function_can_inline_visitor v;
+ const ir_function_signature *callee = call->get_callee();
+
+ v.run((exec_list *) &callee->body);
+
+ ir_instruction *last = (ir_instruction *)callee->body.get_tail();
+ if (last && !last->as_return())
+ v.num_returns++;
+
+ return v.num_returns == 1;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_function_inlining.cpp
+ *
+ * Replaces calls to functions with the body of the function.
+ */
+
+#include <inttypes.h>
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_function_inlining.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+#include "hash_table.h"
+
+class ir_function_inlining_visitor : public ir_hierarchical_visitor {
+public:
+ ir_function_inlining_visitor()
+ {
+ progress = false;
+ }
+
+ virtual ~ir_function_inlining_visitor()
+ {
+ /* empty */
+ }
+
+ virtual ir_visitor_status visit_enter(ir_expression *);
+ virtual ir_visitor_status visit_enter(ir_call *);
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+ virtual ir_visitor_status visit_enter(ir_return *);
+ virtual ir_visitor_status visit_enter(ir_texture *);
+ virtual ir_visitor_status visit_enter(ir_swizzle *);
+
+ bool progress;
+};
+
+
+unsigned int hash_func(const void *key)
+{
+ return (unsigned int)(uintptr_t)key;
+}
+
+int hash_compare_func(const void *key1, const void *key2)
+{
+ return key1 == key2 ? 0 : 1;
+}
+
+bool
+automatic_inlining_predicate(ir_instruction *ir)
+{
+ ir_call *call = ir->as_call();
+
+ if (call && can_inline(call))
+ return true;
+
+ return false;
+}
+
+bool
+do_function_inlining(exec_list *instructions)
+{
+ ir_function_inlining_visitor v;
+
+ do_expression_flattening(instructions, automatic_inlining_predicate);
+
+ v.run(instructions);
+
+ return v.progress;
+}
+
+static void
+replace_return_with_assignment(ir_instruction *ir, void *data)
+{
+ void *ctx = talloc_parent(ir);
+ ir_variable *retval = (ir_variable *)data;
+ ir_return *ret = ir->as_return();
+
+ if (ret) {
+ if (ret->value) {
+ ir_rvalue *lhs = new(ctx) ir_dereference_variable(retval);
+ ret->insert_before(new(ctx) ir_assignment(lhs, ret->value, NULL));
+ ret->remove();
+ } else {
+ /* un-valued return has to be the last return, or we shouldn't
+ * have reached here. (see can_inline()).
+ */
+ assert(!ret->next->is_tail_sentinal());
+ }
+ }
+}
+
+ir_rvalue *
+ir_call::generate_inline(ir_instruction *next_ir)
+{
+ void *ctx = talloc_parent(this);
+ ir_variable **parameters;
+ int num_parameters;
+ int i;
+ ir_variable *retval = NULL;
+ struct hash_table *ht;
+
+ ht = hash_table_ctor(0, hash_func, hash_compare_func);
+
+ num_parameters = 0;
+ foreach_iter(exec_list_iterator, iter_sig, this->callee->parameters)
+ num_parameters++;
+
+ parameters = new ir_variable *[num_parameters];
+
+ /* Generate storage for the return value. */
+ if (this->callee->return_type) {
+ retval = new(ctx) ir_variable(this->callee->return_type, "__retval");
+ next_ir->insert_before(retval);
+ }
+
+ /* Generate the declarations for the parameters to our inlined code,
+ * and set up the mapping of real function body variables to ours.
+ */
+ i = 0;
+ exec_list_iterator sig_param_iter = this->callee->parameters.iterator();
+ exec_list_iterator param_iter = this->actual_parameters.iterator();
+ for (i = 0; i < num_parameters; i++) {
+ const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get();
+ ir_rvalue *param = (ir_rvalue *) param_iter.get();
+
+ /* Generate a new variable for the parameter. */
+ parameters[i] = (ir_variable *)sig_param->clone(ht);
+ parameters[i]->mode = ir_var_auto;
+ next_ir->insert_before(parameters[i]);
+
+ /* Move the actual param into our param variable if it's an 'in' type. */
+ if (sig_param->mode == ir_var_in ||
+ sig_param->mode == ir_var_inout) {
+ ir_assignment *assign;
+
+ assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
+ param, NULL);
+ next_ir->insert_before(assign);
+ }
+
+ sig_param_iter.next();
+ param_iter.next();
+ }
+
+ /* Generate the inlined body of the function. */
+ foreach_iter(exec_list_iterator, iter, callee->body) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_instruction *new_ir = ir->clone(ht);
+
+ next_ir->insert_before(new_ir);
+ visit_tree(new_ir, replace_return_with_assignment, retval);
+ }
+
+ /* Copy back the value of any 'out' parameters from the function body
+ * variables to our own.
+ */
+ i = 0;
+ param_iter = this->actual_parameters.iterator();
+ for (i = 0; i < num_parameters; i++) {
+ ir_instruction *const param = (ir_instruction *) param_iter.get();
+
+ /* Move our param variable into the actual param if it's an 'out' type. */
+ if (parameters[i]->mode == ir_var_out ||
+ parameters[i]->mode == ir_var_inout) {
+ ir_assignment *assign;
+
+ assign = new(ctx) ir_assignment(param->as_rvalue(),
+ new(ctx) ir_dereference_variable(parameters[i]),
+ NULL);
+ next_ir->insert_before(assign);
+ }
+
+ param_iter.next();
+ }
+
+ delete [] parameters;
+
+ hash_table_dtor(ht);
+
+ if (retval)
+ return new(ctx) ir_dereference_variable(retval);
+ else
+ return NULL;
+}
+
+
+ir_visitor_status
+ir_function_inlining_visitor::visit_enter(ir_expression *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_function_inlining_visitor::visit_enter(ir_return *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_function_inlining_visitor::visit_enter(ir_texture *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_function_inlining_visitor::visit_enter(ir_swizzle *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_function_inlining_visitor::visit_enter(ir_call *ir)
+{
+ if (can_inline(ir)) {
+ (void) ir->generate_inline(ir);
+ ir->remove();
+ this->progress = true;
+ }
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+ir_function_inlining_visitor::visit_enter(ir_assignment *ir)
+{
+ ir_call *call = ir->rhs->as_call();
+ if (!call || !can_inline(call))
+ return visit_continue;
+
+ /* generates the parameter setup, function body, and returns the return
+ * value of the function
+ */
+ ir_rvalue *rhs = call->generate_inline(ir);
+ assert(rhs);
+
+ ir->rhs = rhs;
+ this->progress = true;
+
+ return visit_continue;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_function_inlining.h
+ *
+ * Replaces calls to functions with the body of the function.
+ */
+
+bool can_inline(ir_call *call);
--- /dev/null
+/*
+ * 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 "ir.h"
+#include "ir_hierarchical_visitor.h"
+
+ir_hierarchical_visitor::ir_hierarchical_visitor()
+{
+ this->callback = NULL;
+ this->data = NULL;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit(ir_variable *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit(ir_constant *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit(ir_loop_jump *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_loop *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_loop *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_function_signature *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_function *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_function *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_expression *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_expression *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_texture *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_texture *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_swizzle *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_dereference_array *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_dereference_record *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_assignment *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_call *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_call *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_return *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_return *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_if *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_if *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+void
+ir_hierarchical_visitor::run(exec_list *instructions)
+{
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
+
+ if (ir->accept(this) != visit_continue)
+ break;
+ }
+}
+
+
+void
+visit_tree(ir_instruction *ir,
+ void (*callback)(class ir_instruction *ir, void *data),
+ void *data)
+{
+ ir_hierarchical_visitor v;
+
+ v.callback = callback;
+ v.data = data;
+
+ ir->accept(&v);
+}
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef IR_HIERARCHICAL_VISITOR_H
+#define IR_HIERARCHICAL_VISITOR_H
+
+/**
+ * Enumeration values returned by visit methods to guide processing
+ */
+enum ir_visitor_status {
+ visit_continue, /**< Continue visiting as normal. */
+ visit_continue_with_parent, /**< Don't visit siblings, continue w/parent. */
+ visit_stop /**< Stop visiting immediately. */
+};
+
+
+/**
+ * Base class of hierarchical visitors of IR instruction trees
+ *
+ * Hierarchical visitors differ from traditional visitors in a couple of
+ * important ways. Rather than having a single \c visit method for each
+ * subclass in the composite, there are three kinds of visit methods.
+ * Leaf-node classes have a traditional \c visit method. Internal-node
+ * classes have a \c visit_enter method, which is invoked just before
+ * processing child nodes, and a \c visit_leave method which is invoked just
+ * after processing child nodes.
+ *
+ * In addition, each visit method and the \c accept methods in the composite
+ * have a return value which guides the navigation. Any of the visit methods
+ * can choose to continue visiting the tree as normal (by returning \c
+ * visit_continue), terminate visiting any further nodes immediately (by
+ * returning \c visit_stop), or stop visiting sibling nodes (by returning \c
+ * visit_continue_with_parent).
+ *
+ * These two changes combine to allow nagivation of children to be implemented
+ * in the composite's \c accept method. The \c accept method for a leaf-node
+ * class will simply call the \c visit method, as usual, and pass its return
+ * value on. The \c accept method for internal-node classes will call the \c
+ * visit_enter method, call the \c accpet method of each child node, and,
+ * finally, call the \c visit_leave method. If any of these return a value
+ * other that \c visit_continue, the correct action must be taken.
+ *
+ * The final benefit is that the hierarchical visitor base class need not be
+ * abstract. Default implementations of every \c visit, \c visit_enter, and
+ * \c visit_leave method can be provided. By default each of these methods
+ * simply returns \c visit_continue. This allows a significant reduction in
+ * derived class code.
+ *
+ * For more information about hierarchical visitors, see:
+ *
+ * http://c2.com/cgi/wiki?HierarchicalVisitorPattern
+ * http://c2.com/cgi/wiki?HierarchicalVisitorDiscussion
+ */
+
+class ir_hierarchical_visitor {
+public:
+ ir_hierarchical_visitor();
+
+ /**
+ * \name Visit methods for leaf-node classes
+ */
+ /*@{*/
+ virtual ir_visitor_status visit(class ir_variable *);
+ virtual ir_visitor_status visit(class ir_constant *);
+ virtual ir_visitor_status visit(class ir_loop_jump *);
+
+ /**
+ * ir_dereference_variable isn't technically a leaf, but it is treated as a
+ * leaf here for a couple reasons. By not automatically visiting the one
+ * child ir_variable node from the ir_dereference_variable, ir_variable
+ * nodes can always be handled as variable declarations. Code that used
+ * non-hierarchical visitors had to set an "in a dereference" flag to
+ * determine how to handle an ir_variable. By forcing the visitor to
+ * handle the ir_variable within the ir_dereference_variable visitor, this
+ * kludge can be avoided.
+ *
+ * In addition, I can envision no use for having separate enter and leave
+ * methods. Anything that could be done in the enter and leave methods
+ * that couldn't just be done in the visit method.
+ */
+ virtual ir_visitor_status visit(class ir_dereference_variable *);
+ /*@}*/
+
+ /**
+ * \name Visit methods for internal-node classes
+ */
+ /*@{*/
+ virtual ir_visitor_status visit_enter(class ir_loop *);
+ virtual ir_visitor_status visit_leave(class ir_loop *);
+ virtual ir_visitor_status visit_enter(class ir_function_signature *);
+ virtual ir_visitor_status visit_leave(class ir_function_signature *);
+ virtual ir_visitor_status visit_enter(class ir_function *);
+ virtual ir_visitor_status visit_leave(class ir_function *);
+ virtual ir_visitor_status visit_enter(class ir_expression *);
+ virtual ir_visitor_status visit_leave(class ir_expression *);
+ virtual ir_visitor_status visit_enter(class ir_texture *);
+ virtual ir_visitor_status visit_leave(class ir_texture *);
+ virtual ir_visitor_status visit_enter(class ir_swizzle *);
+ virtual ir_visitor_status visit_leave(class ir_swizzle *);
+ virtual ir_visitor_status visit_enter(class ir_dereference_array *);
+ virtual ir_visitor_status visit_leave(class ir_dereference_array *);
+ virtual ir_visitor_status visit_enter(class ir_dereference_record *);
+ virtual ir_visitor_status visit_leave(class ir_dereference_record *);
+ virtual ir_visitor_status visit_enter(class ir_assignment *);
+ virtual ir_visitor_status visit_leave(class ir_assignment *);
+ virtual ir_visitor_status visit_enter(class ir_call *);
+ virtual ir_visitor_status visit_leave(class ir_call *);
+ virtual ir_visitor_status visit_enter(class ir_return *);
+ virtual ir_visitor_status visit_leave(class ir_return *);
+ virtual ir_visitor_status visit_enter(class ir_if *);
+ virtual ir_visitor_status visit_leave(class ir_if *);
+ /*@}*/
+
+
+ /**
+ * Utility function to process a linked list of instructions with a visitor
+ */
+ void run(struct exec_list *instructions);
+
+ /**
+ * Callback function that is invoked on entry to each node visited.
+ *
+ * \warning
+ * Visitor classes derived from \c ir_hierarchical_visitor \b may \b not
+ * invoke this function. This can be used, for example, to cause the
+ * callback to be invoked on every node type execpt one.
+ */
+ void (*callback)(class ir_instruction *ir, void *data);
+
+ /**
+ * Extra data parameter passed to the per-node callback function
+ */
+ void *data;
+};
+
+void visit_tree(ir_instruction *ir,
+ void (*callback)(class ir_instruction *ir, void *data),
+ void *data);
+
+#endif /* IR_HIERARCHICAL_VISITOR_H */
--- /dev/null
+/*
+ * 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 "ir.h"
+
+/**
+ * \file ir_hv_accept.cpp
+ * Implementations of all hierarchical visitor accept methods for IR
+ * instructions.
+ */
+
+/**
+ * Process a list of nodes using a hierarchical vistor
+ *
+ * \warning
+ * This function will operate correctly if a node being processed is removed
+ * from list. However, if nodes are added to the list after the node being
+ * processed, some of the added noded may not be processed.
+ */
+static ir_visitor_status
+visit_list_elements(ir_hierarchical_visitor *v, exec_list *l)
+{
+ exec_node *next;
+
+ for (exec_node *n = l->head; n->next != NULL; n = next) {
+ next = n->next;
+
+ ir_instruction *const ir = (ir_instruction *) n;
+ ir_visitor_status s = ir->accept(v);
+
+ if (s != visit_continue)
+ return s;
+ }
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+ir_variable::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
+ir_visitor_status
+ir_loop::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = visit_list_elements(v, &this->body_instructions);
+ if (s == visit_stop)
+ return s;
+
+ if (s != visit_continue_with_parent) {
+ if (this->from) {
+ s = this->from->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+
+ if (this->to) {
+ s = this->to->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+
+ if (this->increment) {
+ s = this->increment->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+ }
+
+ return v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_loop_jump::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
+ir_visitor_status
+ir_function_signature::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = visit_list_elements(v, &this->body);
+ return (s == visit_stop) ? s : v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_function::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = visit_list_elements(v, &this->signatures);
+ return (s == visit_stop) ? s : v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_expression::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ for (unsigned i = 0; i < this->get_num_operands(); i++) {
+ switch (this->operands[i]->accept(v)) {
+ case visit_continue:
+ break;
+
+ case visit_continue_with_parent:
+ // I wish for Java's labeled break-statement here.
+ goto done;
+
+ case visit_stop:
+ return s;
+ }
+ }
+
+done:
+ return v->visit_leave(this);
+}
+
+ir_visitor_status
+ir_texture::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->sampler->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->coordinate->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ if (this->projector) {
+ s = this->projector->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+
+ if (this->shadow_comparitor) {
+ s = this->shadow_comparitor->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+
+ switch (this->op) {
+ case ir_tex:
+ break;
+ case ir_txb:
+ s = this->lod_info.bias->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ break;
+ case ir_txl:
+ case ir_txf:
+ s = this->lod_info.lod->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ break;
+ case ir_txd:
+ s = this->lod_info.grad.dPdx->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->lod_info.grad.dPdy->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ break;
+ }
+
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
+ir_swizzle::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->val->accept(v);
+ return (s == visit_stop) ? s : v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_dereference_variable::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
+ir_visitor_status
+ir_dereference_array::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->array_index->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->array->accept(v);
+ return (s == visit_stop) ? s : v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_dereference_record::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->record->accept(v);
+ return (s == visit_stop) ? s : v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_assignment::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->lhs->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->rhs->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ if (this->condition)
+ s = this->condition->accept(v);
+
+ return (s == visit_stop) ? s : v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_constant::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
+ir_visitor_status
+ir_call::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = visit_list_elements(v, &this->actual_parameters);
+ if (s == visit_stop)
+ return s;
+
+ return v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_return::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ ir_rvalue *val = this->get_value();
+ if (val) {
+ s = val->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+
+ return v->visit_leave(this);
+}
+
+
+ir_visitor_status
+ir_if::accept(ir_hierarchical_visitor *v)
+{
+ ir_visitor_status s = v->visit_enter(this);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ s = this->condition->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+
+ if (s != visit_continue_with_parent) {
+ s = visit_list_elements(v, &this->then_instructions);
+ if (s == visit_stop)
+ return s;
+ }
+
+ if (s != visit_continue_with_parent) {
+ s = visit_list_elements(v, &this->else_instructions);
+ if (s == visit_stop)
+ return s;
+ }
+
+ return v->visit_leave(this);
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_function_inlining.cpp
+ *
+ * Moves constant branches of if statements out to the surrounding
+ * instruction stream.
+ */
+
+#include "ir.h"
+
+class ir_if_simplification_visitor : public ir_hierarchical_visitor {
+public:
+ ir_if_simplification_visitor()
+ {
+ this->made_progress = false;
+ }
+
+ ir_visitor_status visit_leave(ir_if *);
+
+ bool made_progress;
+};
+
+bool
+do_if_simplification(exec_list *instructions)
+{
+ ir_if_simplification_visitor v;
+
+ v.run(instructions);
+ return v.made_progress;
+}
+
+
+ir_visitor_status
+ir_if_simplification_visitor::visit_leave(ir_if *ir)
+{
+ /* FINISHME: Ideally there would be a way to note that the condition results
+ * FINISHME: in a constant before processing both of the other subtrees.
+ * FINISHME: This can probably be done with some flags, but it would take
+ * FINISHME: some work to get right.
+ */
+ ir_constant *condition_constant = ir->condition->constant_expression_value();
+ if (condition_constant) {
+ /* Move the contents of the one branch of the conditional
+ * that matters out.
+ */
+ if (condition_constant->value.b[0]) {
+ foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
+ ir_instruction *then_ir = (ir_instruction *)then_iter.get();
+ ir->insert_before(then_ir);
+ }
+ } else {
+ foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
+ ir_instruction *else_ir = (ir_instruction *)else_iter.get();
+ ir->insert_before(else_ir);
+ }
+ }
+ ir->remove();
+ this->made_progress = true;
+ }
+
+ return visit_continue;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+
+/**
+ * \file ir_dead_code.h
+ *
+ * Prototypes for optimization passes to be called by the compiler and drivers.
+ */
+
+bool do_constant_folding(exec_list *instructions);
+bool do_constant_variable(exec_list *instructions);
+bool do_constant_variable_unlinked(exec_list *instructions);
+bool do_copy_propagation(exec_list *instructions);
+bool do_dead_code(exec_list *instructions);
+bool do_dead_code_local(exec_list *instructions);
+bool do_dead_code_unlinked(exec_list *instructions);
+bool do_function_inlining(exec_list *instructions);
+bool do_if_simplification(exec_list *instructions);
+bool do_swizzle_swizzle(exec_list *instructions);
+bool do_vec_index_to_swizzle(exec_list *instructions);
--- /dev/null
+/*
+ * 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 "ir_print_visitor.h"
+#include "glsl_types.h"
+#include "glsl_parser_extras.h"
+
+static void print_type(const glsl_type *t);
+
+void
+ir_instruction::print(void) const
+{
+ ir_instruction *deconsted = const_cast<ir_instruction *>(this);
+
+ ir_print_visitor v;
+ deconsted->accept(&v);
+}
+
+void
+_mesa_print_ir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ for (unsigned i = 0; i < state->num_user_structures; i++) {
+ const glsl_type *const s = state->user_structures[i];
+
+ printf("(structure (%s) (%s@%p) (%u) (\n",
+ s->name, s->name, s, s->length);
+
+ for (unsigned j = 0; j < s->length; j++) {
+ printf("\t((");
+ print_type(s->fields.structure[j].type);
+ printf(")(%s))\n", s->fields.structure[j].name);
+ }
+
+ printf(")\n");
+ }
+
+ printf("(\n");
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ((ir_instruction *)iter.get())->print();
+ printf("\n");
+ }
+ printf("\n)");
+}
+
+static void
+print_type(const glsl_type *t)
+{
+ if (t->base_type == GLSL_TYPE_ARRAY) {
+ printf("(array ");
+ print_type(t->fields.array);
+ printf(" %u)", t->length);
+ } else if ((t->base_type == GLSL_TYPE_STRUCT)
+ && (strncmp("gl_", t->name, 3) != 0)) {
+ printf("%s@%p", t->name, t);
+ } else {
+ printf("%s", t->name);
+ }
+}
+
+
+void ir_print_visitor::visit(ir_variable *ir)
+{
+ printf("(declare ");
+
+ const char *const cent = (ir->centroid) ? "centroid " : "";
+ const char *const inv = (ir->invariant) ? "invariant " : "";
+ const char *const mode[] = { "", "uniform ", "in ", "out ", "inout " };
+ const char *const interp[] = { "", "flat", "noperspective" };
+
+ printf("(%s%s%s%s) ",
+ cent, inv, mode[ir->mode], interp[ir->interpolation]);
+
+ print_type(ir->type);
+ printf(" %s@%p)", ir->name, ir);
+}
+
+
+void ir_print_visitor::visit(ir_function_signature *ir)
+{
+ printf("(signature ");
+ print_type(ir->return_type);
+ printf("\n (parameters\n");
+ foreach_iter(exec_list_iterator, iter, ir->parameters) {
+ ir_variable *const inst = (ir_variable *) iter.get();
+
+ inst->accept(this);
+ printf("\n");
+ }
+ printf(" )\n(");
+
+ foreach_iter(exec_list_iterator, iter, ir->body) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ inst->accept(this);
+ printf("\n");
+ }
+ printf("))\n");
+}
+
+
+void ir_print_visitor::visit(ir_function *ir)
+{
+ printf("(function %s\n", ir->name);
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_function_signature *const sig = (ir_function_signature *) iter.get();
+
+ sig->accept(this);
+ printf("\n");
+ }
+
+ printf(")\n");
+}
+
+
+void ir_print_visitor::visit(ir_expression *ir)
+{
+ printf("(expression ");
+
+ print_type(ir->type);
+
+ printf(" %s ", ir->operator_string());
+
+ if (ir->operands[0])
+ ir->operands[0]->accept(this);
+
+ if (ir->operands[1])
+ ir->operands[1]->accept(this);
+ printf(") ");
+}
+
+
+void ir_print_visitor::visit(ir_texture *ir)
+{
+ printf("(%s ", ir->opcode_string());
+
+ ir->sampler->accept(this);
+ printf(" ");
+
+ ir->coordinate->accept(this);
+
+ printf(" (%d %d %d) ", ir->offsets[0], ir->offsets[1], ir->offsets[2]);
+
+ if (ir->op != ir_txf) {
+ if (ir->projector)
+ ir->projector->accept(this);
+ else
+ printf("1");
+
+ if (ir->shadow_comparitor) {
+ printf(" ");
+ ir->shadow_comparitor->accept(this);
+ } else {
+ printf(" ()");
+ }
+ }
+
+ printf(" ");
+ switch (ir->op)
+ {
+ case ir_tex:
+ break;
+ case ir_txb:
+ ir->lod_info.bias->accept(this);
+ break;
+ case ir_txl:
+ case ir_txf:
+ ir->lod_info.lod->accept(this);
+ break;
+ case ir_txd:
+ printf("(");
+ ir->lod_info.grad.dPdx->accept(this);
+ printf(" ");
+ ir->lod_info.grad.dPdy->accept(this);
+ printf(")");
+ break;
+ };
+ printf(")");
+}
+
+
+void ir_print_visitor::visit(ir_swizzle *ir)
+{
+ const unsigned swiz[4] = {
+ ir->mask.x,
+ ir->mask.y,
+ ir->mask.z,
+ ir->mask.w,
+ };
+
+ printf("(swiz ");
+ for (unsigned i = 0; i < ir->mask.num_components; i++) {
+ printf("%c", "xyzw"[swiz[i]]);
+ }
+ printf(" ");
+ ir->val->accept(this);
+ printf(")");
+}
+
+
+void ir_print_visitor::visit(ir_dereference_variable *ir)
+{
+ ir_variable *var = ir->variable_referenced();
+ printf("(var_ref %s@%p) ", var->name, var);
+}
+
+
+void ir_print_visitor::visit(ir_dereference_array *ir)
+{
+ printf("(array_ref ");
+ ir->array->accept(this);
+ ir->array_index->accept(this);
+ printf(") ");
+}
+
+
+void ir_print_visitor::visit(ir_dereference_record *ir)
+{
+ printf("(record_ref ");
+ ir->record->accept(this);
+ printf(" %s) ", ir->field);
+}
+
+
+void ir_print_visitor::visit(ir_assignment *ir)
+{
+ printf("(assign ");
+
+ if (ir->condition)
+ ir->condition->accept(this);
+ else
+ printf("(constant bool (1))");
+
+ printf(" ");
+
+ ir->lhs->accept(this);
+
+ printf(" ");
+
+ ir->rhs->accept(this);
+ printf(") ");
+}
+
+
+void ir_print_visitor::visit(ir_constant *ir)
+{
+ const glsl_type *const base_type = ir->type->get_base_type();
+
+ printf("(constant ");
+ print_type(ir->type);
+ printf(" (");
+
+ for (unsigned i = 0; i < ir->type->components(); i++) {
+ if (i != 0)
+ printf(", ");
+
+ switch (base_type->base_type) {
+ case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break;
+ case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break;
+ case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
+ case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break;
+ default: assert(0);
+ }
+ }
+ printf(")) ");
+}
+
+
+void
+ir_print_visitor::visit(ir_call *ir)
+{
+ printf("(call %s (", ir->callee_name());
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ inst->accept(this);
+ }
+ printf("))\n");
+}
+
+
+void
+ir_print_visitor::visit(ir_return *ir)
+{
+ printf("(return");
+
+ ir_rvalue *const value = ir->get_value();
+ if (value) {
+ printf(" ");
+ value->accept(this);
+ }
+
+ printf(")");
+}
+
+
+void
+ir_print_visitor::visit(ir_if *ir)
+{
+ printf("(if ");
+ ir->condition->accept(this);
+
+ printf("(\n");
+ foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ inst->accept(this);
+ printf("\n");
+ }
+ printf(")\n");
+
+ printf("(\n");
+ foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ inst->accept(this);
+ printf("\n");
+ }
+ printf("))\n");
+}
+
+
+void
+ir_print_visitor::visit(ir_loop *ir)
+{
+ printf("(loop (");
+ if (ir->counter != NULL)
+ ir->counter->accept(this);
+ printf(") (");
+ if (ir->from != NULL)
+ ir->from->accept(this);
+ printf(") (");
+ if (ir->to != NULL)
+ ir->to->accept(this);
+ printf(") (");
+ if (ir->increment != NULL)
+ ir->increment->accept(this);
+ printf(") (\n");
+ foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ inst->accept(this);
+ printf("\n");
+ }
+ printf("))\n");
+}
+
+
+void
+ir_print_visitor::visit(ir_loop_jump *ir)
+{
+ printf("%s", ir->is_break() ? "break" : "continue");
+}
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef IR_PRINT_VISITOR_H
+#define IR_PRINT_VISITOR_H
+
+#include "ir.h"
+#include "ir_visitor.h"
+
+extern void _mesa_print_ir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+/**
+ * Abstract base class of visitors of IR instruction trees
+ */
+class ir_print_visitor : public ir_visitor {
+public:
+ ir_print_visitor()
+ : deref_depth(0)
+ {
+ /* empty */
+ }
+
+ virtual ~ir_print_visitor()
+ {
+ /* empty */
+ }
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(ir_variable *);
+ virtual void visit(ir_function_signature *);
+ virtual void visit(ir_function *);
+ virtual void visit(ir_expression *);
+ virtual void visit(ir_texture *);
+ virtual void visit(ir_swizzle *);
+ virtual void visit(ir_dereference_variable *);
+ virtual void visit(ir_dereference_array *);
+ virtual void visit(ir_dereference_record *);
+ virtual void visit(ir_assignment *);
+ virtual void visit(ir_constant *);
+ virtual void visit(ir_call *);
+ virtual void visit(ir_return *);
+ virtual void visit(ir_if *);
+ virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
+ /*@}*/
+
+private:
+ int deref_depth;
+};
+
+#endif /* IR_PRINT_VISITOR_H */
--- /dev/null
+/*
+ * 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 <cstdarg>
+
+extern "C" {
+#include <talloc.h>
+}
+
+#include "ir_reader.h"
+#include "glsl_parser_extras.h"
+#include "glsl_types.h"
+#include "s_expression.h"
+
+static void ir_read_error(_mesa_glsl_parse_state *, s_expression *,
+ const char *fmt, ...);
+static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
+
+static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
+ s_expression *);
+static ir_function *read_function(_mesa_glsl_parse_state *, s_list *,
+ bool skip_body);
+static void read_function_sig(_mesa_glsl_parse_state *, ir_function *,
+ s_list *, bool skip_body);
+
+static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
+ s_expression *, ir_loop *);
+static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
+ s_expression *, ir_loop *);
+static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_list *);
+static ir_if *read_if(_mesa_glsl_parse_state *, s_list *, ir_loop *);
+static ir_loop *read_loop(_mesa_glsl_parse_state *st, s_list *list);
+static ir_return *read_return(_mesa_glsl_parse_state *, s_list *);
+
+static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
+static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *);
+static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *);
+static ir_call *read_call(_mesa_glsl_parse_state *, s_list *);
+static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *);
+static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *);
+static ir_texture *read_texture(_mesa_glsl_parse_state *, s_list *);
+
+static ir_dereference *read_dereference(_mesa_glsl_parse_state *,
+ s_expression *);
+static ir_dereference *read_var_ref(_mesa_glsl_parse_state *, s_list *);
+static ir_dereference *read_array_ref(_mesa_glsl_parse_state *, s_list *);
+static ir_dereference *read_record_ref(_mesa_glsl_parse_state *, s_list *);
+
+void
+_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
+ const char *src)
+{
+ void *ctx = talloc_parent(state);
+ s_expression *expr = s_expression::read_expression(ctx, src);
+ if (expr == NULL) {
+ ir_read_error(state, NULL, "couldn't parse S-Expression.");
+ return;
+ }
+
+ scan_for_prototypes(state, instructions, expr);
+ if (state->error)
+ return;
+
+ read_instructions(state, instructions, expr, NULL);
+}
+
+static void
+ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ state->error = true;
+
+ state->info_log = talloc_strdup_append(state->info_log, "error: ");
+
+ 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");
+
+ if (expr != NULL) {
+ state->info_log = talloc_strdup_append(state->info_log,
+ "...in this context:\n ");
+ expr->print();
+ state->info_log = talloc_strdup_append(state->info_log, "\n\n");
+ }
+}
+
+static const glsl_type *
+read_type(_mesa_glsl_parse_state *st, s_expression *expr)
+{
+ s_list *list = SX_AS_LIST(expr);
+ if (list != NULL) {
+ s_symbol *type_sym = SX_AS_SYMBOL(list->subexpressions.get_head());
+ if (type_sym == NULL) {
+ ir_read_error(st, expr, "expected type (array ...) or (struct ...)");
+ return NULL;
+ }
+ if (strcmp(type_sym->value(), "array") == 0) {
+ if (list->length() != 3) {
+ ir_read_error(st, expr, "expected type (array <type> <int>)");
+ return NULL;
+ }
+
+ // Read base type
+ s_expression *base_expr = (s_expression*) type_sym->next;
+ const glsl_type *base_type = read_type(st, base_expr);
+ if (base_type == NULL) {
+ ir_read_error(st, NULL, "when reading base type of array");
+ return NULL;
+ }
+
+ // Read array size
+ s_int *size = SX_AS_INT(base_expr->next);
+ if (size == NULL) {
+ ir_read_error(st, expr, "found non-integer array size");
+ return NULL;
+ }
+
+ return glsl_type::get_array_instance(st, base_type, size->value());
+ } else if (strcmp(type_sym->value(), "struct") == 0) {
+ assert(false); // FINISHME
+ } else {
+ ir_read_error(st, expr, "expected (array ...) or (struct ...); "
+ "found (%s ...)", type_sym->value());
+ return NULL;
+ }
+ }
+
+ s_symbol *type_sym = SX_AS_SYMBOL(expr);
+ if (type_sym == NULL) {
+ ir_read_error(st, expr, "expected <type> (symbol or list)");
+ return NULL;
+ }
+
+ const glsl_type *type = st->symbols->get_type(type_sym->value());
+ if (type == NULL)
+ ir_read_error(st, expr, "invalid type: %s", type_sym->value());
+
+ return type;
+}
+
+
+static void
+scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
+ s_expression *expr)
+{
+ s_list *list = SX_AS_LIST(expr);
+ if (list == NULL) {
+ ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
+ return;
+ }
+
+ foreach_iter(exec_list_iterator, it, list->subexpressions) {
+ s_list *sub = SX_AS_LIST(it.get());
+ if (sub == NULL)
+ continue; // not a (function ...); ignore it.
+
+ s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
+ if (tag == NULL || strcmp(tag->value(), "function") != 0)
+ continue; // not a (function ...); ignore it.
+
+ ir_function *f = read_function(st, sub, true);
+ if (f == NULL)
+ return;
+ instructions->push_tail(f);
+ }
+}
+
+static ir_function *
+read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() < 3) {
+ ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
+ return NULL;
+ }
+
+ s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
+ if (name == NULL) {
+ ir_read_error(st, list, "Expected (function <name> ...)");
+ return NULL;
+ }
+
+ ir_function *f = st->symbols->get_function(name->value());
+ if (f == NULL) {
+ f = new(ctx) ir_function(name->value());
+ bool added = st->symbols->add_function(name->value(), f);
+ assert(added);
+ }
+
+ exec_list_iterator it = list->subexpressions.iterator();
+ it.next(); // skip "function" tag
+ it.next(); // skip function name
+ for (/* nothing */; it.has_next(); it.next()) {
+ s_list *siglist = SX_AS_LIST(it.get());
+ if (siglist == NULL) {
+ ir_read_error(st, list, "Expected (function (signature ...) ...)");
+ return NULL;
+ }
+
+ s_symbol *tag = SX_AS_SYMBOL(siglist->subexpressions.get_head());
+ if (tag == NULL || strcmp(tag->value(), "signature") != 0) {
+ ir_read_error(st, siglist, "Expected (signature ...)");
+ return NULL;
+ }
+
+ read_function_sig(st, f, siglist, skip_body);
+ }
+ return f;
+}
+
+static void
+read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
+ bool skip_body)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 4) {
+ ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
+ "(<instruction> ...))");
+ return;
+ }
+
+ s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
+ const glsl_type *return_type = read_type(st, type_expr);
+ if (return_type == NULL)
+ return;
+
+ s_list *paramlist = SX_AS_LIST(type_expr->next);
+ s_list *body_list = SX_AS_LIST(paramlist->next);
+ if (paramlist == NULL || body_list == NULL) {
+ ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
+ "(<instruction> ...))");
+ return;
+ }
+ s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
+ if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
+ ir_read_error(st, paramlist, "Expected (parameters ...)");
+ return;
+ }
+
+ // Read the parameters list into a temporary place.
+ exec_list hir_parameters;
+ st->symbols->push_scope();
+
+ exec_list_iterator it = paramlist->subexpressions.iterator();
+ for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
+ s_list *decl = SX_AS_LIST(it.get());
+ ir_variable *var = read_declaration(st, decl);
+ if (var == NULL)
+ return;
+
+ hir_parameters.push_tail(var);
+ }
+
+ ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
+ if (sig != NULL) {
+ const char *badvar = sig->qualifiers_match(&hir_parameters);
+ if (badvar != NULL) {
+ ir_read_error(st, list, "function `%s' parameter `%s' qualifiers "
+ "don't match prototype", f->name, badvar);
+ return;
+ }
+
+ if (sig->return_type != return_type) {
+ ir_read_error(st, list, "function `%s' return type doesn't "
+ "match prototype", f->name);
+ return;
+ }
+ } else {
+ sig = new(ctx) ir_function_signature(return_type);
+ f->add_signature(sig);
+ }
+
+ sig->replace_parameters(&hir_parameters);
+
+ if (!skip_body) {
+ if (sig->is_defined) {
+ ir_read_error(st, list, "function %s redefined", f->name);
+ return;
+ }
+ read_instructions(st, &sig->body, body_list, NULL);
+ sig->is_defined = true;
+ }
+
+ st->symbols->pop_scope();
+}
+
+static void
+read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
+ s_expression *expr, ir_loop *loop_ctx)
+{
+ // Read in a list of instructions
+ s_list *list = SX_AS_LIST(expr);
+ if (list == NULL) {
+ ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
+ return;
+ }
+
+ foreach_iter(exec_list_iterator, it, list->subexpressions) {
+ s_expression *sub = (s_expression*) it.get();
+ ir_instruction *ir = read_instruction(st, sub, loop_ctx);
+ if (ir == NULL) {
+ ir_read_error(st, sub, "Invalid instruction.\n");
+ return;
+ }
+ instructions->push_tail(ir);
+ }
+}
+
+
+static ir_instruction *
+read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
+ ir_loop *loop_ctx)
+{
+ void *ctx = talloc_parent(st);
+ s_symbol *symbol = SX_AS_SYMBOL(expr);
+ if (symbol != NULL) {
+ if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
+ return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+ if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
+ return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+ }
+
+ s_list *list = SX_AS_LIST(expr);
+ if (list == NULL || list->subexpressions.is_empty())
+ return NULL;
+
+ s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
+ if (tag == NULL) {
+ ir_read_error(st, expr, "expected instruction tag");
+ return NULL;
+ }
+
+ ir_instruction *inst = NULL;
+ if (strcmp(tag->value(), "declare") == 0) {
+ inst = read_declaration(st, list);
+ } else if (strcmp(tag->value(), "if") == 0) {
+ inst = read_if(st, list, loop_ctx);
+ } else if (strcmp(tag->value(), "loop") == 0) {
+ inst = read_loop(st, list);
+ } else if (strcmp(tag->value(), "return") == 0) {
+ inst = read_return(st, list);
+ } else if (strcmp(tag->value(), "function") == 0) {
+ inst = read_function(st, list, false);
+ } else {
+ inst = read_rvalue(st, list);
+ if (inst == NULL)
+ ir_read_error(st, NULL, "when reading instruction");
+ }
+ return inst;
+}
+
+
+static ir_variable *
+read_declaration(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 4) {
+ ir_read_error(st, list, "expected (declare (<qualifiers>) <type> "
+ "<name>)");
+ return NULL;
+ }
+
+ s_list *quals = SX_AS_LIST(list->subexpressions.head->next);
+ if (quals == NULL) {
+ ir_read_error(st, list, "expected a list of variable qualifiers");
+ return NULL;
+ }
+
+ s_expression *type_expr = (s_expression*) quals->next;
+ const glsl_type *type = read_type(st, type_expr);
+ if (type == NULL)
+ return NULL;
+
+ s_symbol *var_name = SX_AS_SYMBOL(type_expr->next);
+ if (var_name == NULL) {
+ ir_read_error(st, list, "expected variable name, found non-symbol");
+ return NULL;
+ }
+
+ ir_variable *var = new(ctx) ir_variable(type, var_name->value());
+
+ foreach_iter(exec_list_iterator, it, quals->subexpressions) {
+ s_symbol *qualifier = SX_AS_SYMBOL(it.get());
+ if (qualifier == NULL) {
+ ir_read_error(st, list, "qualifier list must contain only symbols");
+ delete var;
+ return NULL;
+ }
+
+ // FINISHME: Check for duplicate/conflicting qualifiers.
+ if (strcmp(qualifier->value(), "centroid") == 0) {
+ var->centroid = 1;
+ } else if (strcmp(qualifier->value(), "invariant") == 0) {
+ var->invariant = 1;
+ } else if (strcmp(qualifier->value(), "uniform") == 0) {
+ var->mode = ir_var_uniform;
+ } else if (strcmp(qualifier->value(), "auto") == 0) {
+ var->mode = ir_var_auto;
+ } else if (strcmp(qualifier->value(), "in") == 0) {
+ var->mode = ir_var_in;
+ } else if (strcmp(qualifier->value(), "out") == 0) {
+ var->mode = ir_var_out;
+ } else if (strcmp(qualifier->value(), "inout") == 0) {
+ var->mode = ir_var_inout;
+ } else if (strcmp(qualifier->value(), "smooth") == 0) {
+ var->interpolation = ir_var_smooth;
+ } else if (strcmp(qualifier->value(), "flat") == 0) {
+ var->interpolation = ir_var_flat;
+ } else if (strcmp(qualifier->value(), "noperspective") == 0) {
+ var->interpolation = ir_var_noperspective;
+ } else {
+ ir_read_error(st, list, "unknown qualifier: %s", qualifier->value());
+ delete var;
+ return NULL;
+ }
+ }
+
+ // Add the variable to the symbol table
+ st->symbols->add_variable(var_name->value(), var);
+
+ return var;
+}
+
+
+static ir_if *
+read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 4) {
+ ir_read_error(st, list, "expected (if <condition> (<then> ...) "
+ "(<else> ...))");
+ return NULL;
+ }
+
+ s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
+ ir_rvalue *condition = read_rvalue(st, cond_expr);
+ if (condition == NULL) {
+ ir_read_error(st, NULL, "when reading condition of (if ...)");
+ return NULL;
+ }
+
+ s_expression *then_expr = (s_expression*) cond_expr->next;
+ s_expression *else_expr = (s_expression*) then_expr->next;
+
+ ir_if *iff = new(ctx) ir_if(condition);
+
+ read_instructions(st, &iff->then_instructions, then_expr, loop_ctx);
+ read_instructions(st, &iff->else_instructions, else_expr, loop_ctx);
+ if (st->error) {
+ delete iff;
+ iff = NULL;
+ }
+ return iff;
+}
+
+
+static ir_loop *
+read_loop(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 6) {
+ ir_read_error(st, list, "expected (loop <counter> <from> <to> "
+ "<increment> <body>)");
+ return NULL;
+ }
+
+ s_expression *count_expr = (s_expression*) list->subexpressions.head->next;
+ s_expression *from_expr = (s_expression*) count_expr->next;
+ s_expression *to_expr = (s_expression*) from_expr->next;
+ s_expression *inc_expr = (s_expression*) to_expr->next;
+ s_expression *body_expr = (s_expression*) inc_expr->next;
+
+ // FINISHME: actually read the count/from/to fields.
+
+ ir_loop *loop = new(ctx) ir_loop;
+ read_instructions(st, &loop->body_instructions, body_expr, loop);
+ if (st->error) {
+ delete loop;
+ loop = NULL;
+ }
+ return loop;
+}
+
+
+static ir_return *
+read_return(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 2) {
+ ir_read_error(st, list, "expected (return <rvalue>)");
+ return NULL;
+ }
+
+ s_expression *expr = (s_expression*) list->subexpressions.head->next;
+
+ ir_rvalue *retval = read_rvalue(st, expr);
+ if (retval == NULL) {
+ ir_read_error(st, NULL, "when reading return value");
+ return NULL;
+ }
+
+ return new(ctx) ir_return(retval);
+}
+
+
+static ir_rvalue *
+read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
+{
+ s_list *list = SX_AS_LIST(expr);
+ if (list == NULL || list->subexpressions.is_empty())
+ return NULL;
+
+ s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
+ if (tag == NULL) {
+ ir_read_error(st, expr, "expected rvalue tag");
+ return NULL;
+ }
+
+ ir_rvalue *rvalue = read_dereference(st, list);
+ if (rvalue != NULL || st->error)
+ return rvalue;
+ else if (strcmp(tag->value(), "swiz") == 0) {
+ rvalue = read_swizzle(st, list);
+ } else if (strcmp(tag->value(), "assign") == 0) {
+ rvalue = read_assignment(st, list);
+ } else if (strcmp(tag->value(), "expression") == 0) {
+ rvalue = read_expression(st, list);
+ } else if (strcmp(tag->value(), "call") == 0) {
+ rvalue = read_call(st, list);
+ } else if (strcmp(tag->value(), "constant") == 0) {
+ rvalue = read_constant(st, list);
+ } else {
+ rvalue = read_texture(st, list);
+ if (rvalue == NULL && !st->error)
+ ir_read_error(st, expr, "unrecognized rvalue tag: %s", tag->value());
+ }
+
+ return rvalue;
+}
+
+static ir_assignment *
+read_assignment(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 4) {
+ ir_read_error(st, list, "expected (assign <condition> <lhs> <rhs>)");
+ return NULL;
+ }
+
+ s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
+ s_expression *lhs_expr = (s_expression*) cond_expr->next;
+ s_expression *rhs_expr = (s_expression*) lhs_expr->next;
+
+ // FINISHME: Deal with "true" condition
+ ir_rvalue *condition = read_rvalue(st, cond_expr);
+ if (condition == NULL) {
+ ir_read_error(st, NULL, "when reading condition of assignment");
+ return NULL;
+ }
+
+ ir_rvalue *lhs = read_rvalue(st, lhs_expr);
+ if (lhs == NULL) {
+ ir_read_error(st, NULL, "when reading left-hand side of assignment");
+ return NULL;
+ }
+
+ ir_rvalue *rhs = read_rvalue(st, rhs_expr);
+ if (rhs == NULL) {
+ ir_read_error(st, NULL, "when reading right-hand side of assignment");
+ return NULL;
+ }
+
+ return new(ctx) ir_assignment(lhs, rhs, condition);
+}
+
+static ir_call *
+read_call(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 3) {
+ ir_read_error(st, list, "expected (call <name> (<param> ...))");
+ return NULL;
+ }
+
+ s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
+ s_list *params = SX_AS_LIST(name->next);
+ if (name == NULL || params == NULL) {
+ ir_read_error(st, list, "expected (call <name> (<param> ...))");
+ return NULL;
+ }
+
+ exec_list parameters;
+
+ foreach_iter(exec_list_iterator, it, params->subexpressions) {
+ s_expression *expr = (s_expression*) it.get();
+ ir_rvalue *param = read_rvalue(st, expr);
+ if (param == NULL) {
+ ir_read_error(st, list, "when reading parameter to function call");
+ return NULL;
+ }
+ parameters.push_tail(param);
+ }
+
+ ir_function *f = st->symbols->get_function(name->value());
+ if (f == NULL) {
+ ir_read_error(st, list, "found call to undefined function %s",
+ name->value());
+ return NULL;
+ }
+
+ const ir_function_signature *callee = f->matching_signature(¶meters);
+ if (callee == NULL) {
+ ir_read_error(st, list, "couldn't find matching signature for function "
+ "%s", name->value());
+ return NULL;
+ }
+
+ return new(ctx) ir_call(callee, ¶meters);
+}
+
+static ir_expression *
+read_expression(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ const unsigned list_length = list->length();
+ if (list_length < 4) {
+ ir_read_error(st, list, "expected (expression <type> <operator> "
+ "<operand> [<operand>])");
+ return NULL;
+ }
+
+ s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
+ const glsl_type *type = read_type(st, type_expr);
+ if (type == NULL)
+ return NULL;
+
+ /* Read the operator */
+ s_symbol *op_sym = SX_AS_SYMBOL(type_expr->next);
+ if (op_sym == NULL) {
+ ir_read_error(st, list, "expected operator, found non-symbol");
+ return NULL;
+ }
+
+ ir_expression_operation op = ir_expression::get_operator(op_sym->value());
+ if (op == (ir_expression_operation) -1) {
+ ir_read_error(st, list, "invalid operator: %s", op_sym->value());
+ return NULL;
+ }
+
+ /* Now that we know the operator, check for the right number of operands */
+ if (ir_expression::get_num_operands(op) == 2) {
+ if (list_length != 5) {
+ ir_read_error(st, list, "expected (expression <type> %s <operand> "
+ " <operand>)", op_sym->value());
+ return NULL;
+ }
+ } else {
+ if (list_length != 4) {
+ ir_read_error(st, list, "expected (expression <type> %s <operand>)",
+ op_sym->value());
+ return NULL;
+ }
+ }
+
+ s_expression *exp1 = (s_expression*) (op_sym->next);
+ ir_rvalue *arg1 = read_rvalue(st, exp1);
+ if (arg1 == NULL) {
+ ir_read_error(st, NULL, "when reading first operand of %s",
+ op_sym->value());
+ return NULL;
+ }
+
+ ir_rvalue *arg2 = NULL;
+ if (ir_expression::get_num_operands(op) == 2) {
+ s_expression *exp2 = (s_expression*) (exp1->next);
+ arg2 = read_rvalue(st, exp2);
+ if (arg2 == NULL) {
+ ir_read_error(st, NULL, "when reading second operand of %s",
+ op_sym->value());
+ return NULL;
+ }
+ }
+
+ return new(ctx) ir_expression(op, type, arg1, arg2);
+}
+
+static ir_swizzle *
+read_swizzle(_mesa_glsl_parse_state *st, s_list *list)
+{
+ if (list->length() != 3) {
+ ir_read_error(st, list, "expected (swiz <swizzle> <rvalue>)");
+ return NULL;
+ }
+
+ s_symbol *swiz = SX_AS_SYMBOL(list->subexpressions.head->next);
+ if (swiz == NULL) {
+ ir_read_error(st, list, "expected a valid swizzle; found non-symbol");
+ return NULL;
+ }
+
+ if (strlen(swiz->value()) > 4) {
+ ir_read_error(st, list, "expected a valid swizzle; found %s",
+ swiz->value());
+ return NULL;
+ }
+
+ s_expression *sub = (s_expression*) swiz->next;
+ if (sub == NULL) {
+ ir_read_error(st, list, "expected rvalue: (swizzle %s <rvalue>)",
+ swiz->value());
+ return NULL;
+ }
+
+ ir_rvalue *rvalue = read_rvalue(st, sub);
+ if (rvalue == NULL)
+ return NULL;
+
+ ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
+ rvalue->type->vector_elements);
+ if (ir == NULL)
+ ir_read_error(st, list, "invalid swizzle");
+
+ return ir;
+}
+
+static ir_constant *
+read_constant(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 3) {
+ ir_read_error(st, list, "expected (constant <type> (<num> ... <num>))");
+ return NULL;
+ }
+
+ s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
+ const glsl_type *type = read_type(st, type_expr);
+ if (type == NULL)
+ return NULL;
+
+ s_list *values = SX_AS_LIST(type_expr->next);
+ if (values == NULL) {
+ ir_read_error(st, list, "expected (constant <type> (<num> ... <num>))");
+ return NULL;
+ }
+
+ const glsl_type *const base_type = type->get_base_type();
+
+ ir_constant_data data;
+
+ // Read in list of values (at most 16).
+ int k = 0;
+ foreach_iter(exec_list_iterator, it, values->subexpressions) {
+ if (k >= 16) {
+ ir_read_error(st, values, "expected at most 16 numbers");
+ return NULL;
+ }
+
+ s_expression *expr = (s_expression*) it.get();
+
+ if (base_type->base_type == GLSL_TYPE_FLOAT) {
+ s_number *value = SX_AS_NUMBER(expr);
+ if (value == NULL) {
+ ir_read_error(st, values, "expected numbers");
+ return NULL;
+ }
+ data.f[k] = value->fvalue();
+ } else {
+ s_int *value = SX_AS_INT(expr);
+ if (value == NULL) {
+ ir_read_error(st, values, "expected integers");
+ return NULL;
+ }
+
+ switch (base_type->base_type) {
+ case GLSL_TYPE_UINT: {
+ data.u[k] = value->value();
+ break;
+ }
+ case GLSL_TYPE_INT: {
+ data.i[k] = value->value();
+ break;
+ }
+ case GLSL_TYPE_BOOL: {
+ data.b[k] = value->value();
+ break;
+ }
+ default:
+ ir_read_error(st, values, "unsupported constant type");
+ return NULL;
+ }
+ }
+ ++k;
+ }
+
+ return new(ctx) ir_constant(type, &data);
+}
+
+static ir_dereference *
+read_dereference(_mesa_glsl_parse_state *st, s_expression *expr)
+{
+ s_list *list = SX_AS_LIST(expr);
+ if (list == NULL || list->subexpressions.is_empty())
+ return NULL;
+
+ s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
+ assert(tag != NULL);
+
+ if (strcmp(tag->value(), "var_ref") == 0)
+ return read_var_ref(st, list);
+ if (strcmp(tag->value(), "array_ref") == 0)
+ return read_array_ref(st, list);
+ if (strcmp(tag->value(), "record_ref") == 0)
+ return read_record_ref(st, list);
+ return NULL;
+}
+
+static ir_dereference *
+read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 2) {
+ ir_read_error(st, list, "expected (var_ref <variable name>)");
+ return NULL;
+ }
+ s_symbol *var_name = SX_AS_SYMBOL(list->subexpressions.head->next);
+ if (var_name == NULL) {
+ ir_read_error(st, list, "expected (var_ref <variable name>)");
+ return NULL;
+ }
+
+ ir_variable *var = st->symbols->get_variable(var_name->value());
+ if (var == NULL) {
+ ir_read_error(st, list, "undeclared variable: %s", var_name->value());
+ return NULL;
+ }
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+static ir_dereference *
+read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 3) {
+ ir_read_error(st, list, "expected (array_ref <rvalue> <index>)");
+ return NULL;
+ }
+
+ s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
+ ir_rvalue *subject = read_rvalue(st, subj_expr);
+ if (subject == NULL) {
+ ir_read_error(st, NULL, "when reading the subject of an array_ref");
+ return NULL;
+ }
+
+ s_expression *idx_expr = (s_expression*) subj_expr->next;
+ ir_rvalue *idx = read_rvalue(st, idx_expr);
+ return new(ctx) ir_dereference_array(subject, idx);
+}
+
+static ir_dereference *
+read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ if (list->length() != 3) {
+ ir_read_error(st, list, "expected (record_ref <rvalue> <field>)");
+ return NULL;
+ }
+
+ s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
+ ir_rvalue *subject = read_rvalue(st, subj_expr);
+ if (subject == NULL) {
+ ir_read_error(st, NULL, "when reading the subject of a record_ref");
+ return NULL;
+ }
+
+ s_symbol *field = SX_AS_SYMBOL(subj_expr->next);
+ if (field == NULL) {
+ ir_read_error(st, list, "expected (record_ref ... <field name>)");
+ return NULL;
+ }
+ return new(ctx) ir_dereference_record(subject, field->value());
+}
+
+static bool
+valid_texture_list_length(ir_texture_opcode op, s_list *list)
+{
+ unsigned required_length = 7;
+ if (op == ir_txf)
+ required_length = 5;
+ else if (op == ir_tex)
+ required_length = 6;
+
+ return list->length() == required_length;
+}
+
+static ir_texture *
+read_texture(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = talloc_parent(st);
+ s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
+ assert(tag != NULL);
+
+ ir_texture_opcode op = ir_texture::get_opcode(tag->value());
+ if (op == (ir_texture_opcode) -1)
+ return NULL;
+
+ if (!valid_texture_list_length(op, list)) {
+ ir_read_error(st, NULL, "invalid list size in (%s ...)", tag->value());
+ return NULL;
+ }
+
+ ir_texture *tex = new(ctx) ir_texture(op);
+
+ // Read sampler (must be a deref)
+ s_expression *sampler_expr = (s_expression *) tag->next;
+ ir_dereference *sampler = read_dereference(st, sampler_expr);
+ if (sampler == NULL) {
+ ir_read_error(st, NULL, "when reading sampler in (%s ...)", tag->value());
+ return NULL;
+ }
+ tex->set_sampler(sampler);
+
+ // Read coordinate (any rvalue)
+ s_expression *coordinate_expr = (s_expression *) sampler_expr->next;
+ tex->coordinate = read_rvalue(st, coordinate_expr);
+ if (tex->coordinate == NULL) {
+ ir_read_error(st, NULL, "when reading coordinate in (%s ...)",
+ tag->value());
+ return NULL;
+ }
+
+ // Read texel offset, i.e. (0 0 0)
+ s_list *offset_list = SX_AS_LIST(coordinate_expr->next);
+ if (offset_list == NULL || offset_list->length() != 3) {
+ ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
+ return NULL;
+ }
+ s_int *offset_x = SX_AS_INT(offset_list->subexpressions.head);
+ s_int *offset_y = SX_AS_INT(offset_x->next);
+ s_int *offset_z = SX_AS_INT(offset_y->next);
+ if (offset_x == NULL || offset_y == NULL || offset_z == NULL) {
+ ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
+ return NULL;
+ }
+ tex->offsets[0] = offset_x->value();
+ tex->offsets[1] = offset_y->value();
+ tex->offsets[2] = offset_z->value();
+
+ if (op == ir_txf) {
+ s_expression *lod_expr = (s_expression *) offset_list->next;
+ tex->lod_info.lod = read_rvalue(st, lod_expr);
+ if (tex->lod_info.lod == NULL) {
+ ir_read_error(st, NULL, "when reading LOD in (txf ...)");
+ return NULL;
+ }
+ } else {
+ s_expression *proj_expr = (s_expression *) offset_list->next;
+ s_int *proj_as_int = SX_AS_INT(proj_expr);
+ if (proj_as_int && proj_as_int->value() == 1) {
+ tex->projector = NULL;
+ } else {
+ tex->projector = read_rvalue(st, proj_expr);
+ if (tex->projector == NULL) {
+ ir_read_error(st, NULL, "when reading projective divide in (%s ..)",
+ tag->value());
+ return NULL;
+ }
+ }
+
+ s_list *shadow_list = SX_AS_LIST(proj_expr->next);
+ if (shadow_list == NULL) {
+ ir_read_error(st, NULL, "shadow comparitor must be a list");
+ return NULL;
+ }
+ if (shadow_list->subexpressions.is_empty()) {
+ tex->shadow_comparitor= NULL;
+ } else {
+ tex->shadow_comparitor = read_rvalue(st, shadow_list);
+ if (tex->shadow_comparitor == NULL) {
+ ir_read_error(st, NULL, "when reading shadow comparitor in (%s ..)",
+ tag->value());
+ return NULL;
+ }
+ }
+ s_expression *lod_expr = (s_expression *) shadow_list->next;
+
+ switch (op) {
+ case ir_txb:
+ tex->lod_info.bias = read_rvalue(st, lod_expr);
+ if (tex->lod_info.bias == NULL) {
+ ir_read_error(st, NULL, "when reading LOD bias in (txb ...)");
+ return NULL;
+ }
+ break;
+ case ir_txl:
+ tex->lod_info.lod = read_rvalue(st, lod_expr);
+ if (tex->lod_info.lod == NULL) {
+ ir_read_error(st, NULL, "when reading LOD in (txl ...)");
+ return NULL;
+ }
+ break;
+ case ir_txd: {
+ s_list *lod_list = SX_AS_LIST(lod_expr);
+ if (lod_list->length() != 2) {
+ ir_read_error(st, lod_expr, "expected (dPdx dPdy) in (txd ...)");
+ return NULL;
+ }
+ s_expression *dx_expr = (s_expression *) lod_list->subexpressions.head;
+ s_expression *dy_expr = (s_expression *) dx_expr->next;
+
+ tex->lod_info.grad.dPdx = read_rvalue(st, dx_expr);
+ if (tex->lod_info.grad.dPdx == NULL) {
+ ir_read_error(st, NULL, "when reading dPdx in (txd ...)");
+ return NULL;
+ }
+ tex->lod_info.grad.dPdy = read_rvalue(st, dy_expr);
+ if (tex->lod_info.grad.dPdy == NULL) {
+ ir_read_error(st, NULL, "when reading dPdy in (txd ...)");
+ return NULL;
+ }
+ break;
+ }
+ default:
+ // tex doesn't have any extra parameters and txf was handled earlier.
+ break;
+ };
+ }
+ return tex;
+}
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef IR_READER_H
+#define IR_READER_H
+
+#include "ir.h"
+
+void _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
+ const char *src);
+
+#endif /* IR_READER_H */
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_swizzle_swizzle.cpp
+ *
+ * Eliminates the second swizzle in a swizzle chain.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+class ir_swizzle_swizzle_visitor : public ir_hierarchical_visitor {
+public:
+ ir_swizzle_swizzle_visitor()
+ {
+ progress = false;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_swizzle *);
+
+ bool progress;
+};
+
+ir_visitor_status
+ir_swizzle_swizzle_visitor::visit_enter(ir_swizzle *ir)
+{
+ int mask2[4];
+
+ ir_swizzle *swiz2 = ir->val->as_swizzle();
+ if (!swiz2)
+ return visit_continue;
+
+ memset(&mask2, 0, sizeof(mask2));
+ if (swiz2->mask.num_components >= 1)
+ mask2[0] = swiz2->mask.x;
+ if (swiz2->mask.num_components >= 2)
+ mask2[1] = swiz2->mask.y;
+ if (swiz2->mask.num_components >= 3)
+ mask2[2] = swiz2->mask.z;
+ if (swiz2->mask.num_components >= 4)
+ mask2[3] = swiz2->mask.w;
+
+ if (ir->mask.num_components >= 1)
+ ir->mask.x = mask2[ir->mask.x];
+ if (ir->mask.num_components >= 2)
+ ir->mask.y = mask2[ir->mask.y];
+ if (ir->mask.num_components >= 3)
+ ir->mask.z = mask2[ir->mask.z];
+ if (ir->mask.num_components >= 4)
+ ir->mask.w = mask2[ir->mask.w];
+
+ ir->val = swiz2->val;
+
+ this->progress = true;
+
+ return visit_continue;
+}
+
+/**
+ * Does a copy propagation pass on the code present in the instruction stream.
+ */
+bool
+do_swizzle_swizzle(exec_list *instructions)
+{
+ ir_swizzle_swizzle_visitor v;
+
+ v.run(instructions);
+
+ return v.progress;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_to_mesa.cpp
+ *
+ * Translates the IR to ARB_fragment_program text if possible,
+ * printing the result
+ */
+
+#include <stdio.h>
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_print_visitor.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+
+extern "C" {
+#include "shader/prog_instruction.h"
+#include "shader/prog_print.h"
+}
+
+/**
+ * This struct is a corresponding struct to Mesa prog_src_register, with
+ * wider fields.
+ */
+typedef struct ir_to_mesa_src_reg {
+ int file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+ int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
+ int negate; /**< NEGATE_XYZW mask from mesa */
+ bool reladdr; /**< Register index should be offset by address reg. */
+} ir_to_mesa_src_reg;
+
+typedef struct ir_to_mesa_dst_reg {
+ int file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+ int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
+} ir_to_mesa_dst_reg;
+
+extern ir_to_mesa_src_reg ir_to_mesa_undef;
+
+class ir_to_mesa_instruction : public exec_node {
+public:
+ enum prog_opcode op;
+ ir_to_mesa_dst_reg dst_reg;
+ ir_to_mesa_src_reg src_reg[3];
+ /** Pointer to the ir source this tree came from for debugging */
+ ir_instruction *ir;
+};
+
+class temp_entry : public exec_node {
+public:
+ temp_entry(ir_variable *var, int file, int index)
+ : file(file), index(index), var(var)
+ {
+ /* empty */
+ }
+
+ int file;
+ int index;
+ ir_variable *var; /* variable that maps to this, if any */
+};
+
+class ir_to_mesa_visitor : public ir_visitor {
+public:
+ ir_to_mesa_visitor();
+
+ int next_temp;
+ int next_constant;
+ int next_uniform;
+
+ temp_entry *find_variable_storage(ir_variable *var);
+
+ ir_to_mesa_src_reg get_temp(const glsl_type *type);
+
+ struct ir_to_mesa_src_reg src_reg_for_float(float val);
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(ir_variable *);
+ virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
+ virtual void visit(ir_function_signature *);
+ virtual void visit(ir_function *);
+ virtual void visit(ir_expression *);
+ virtual void visit(ir_swizzle *);
+ virtual void visit(ir_dereference_variable *);
+ virtual void visit(ir_dereference_array *);
+ virtual void visit(ir_dereference_record *);
+ virtual void visit(ir_assignment *);
+ virtual void visit(ir_constant *);
+ virtual void visit(ir_call *);
+ virtual void visit(ir_return *);
+ virtual void visit(ir_texture *);
+ virtual void visit(ir_if *);
+ /*@}*/
+
+ struct ir_to_mesa_src_reg result;
+
+ /** List of temp_entry */
+ exec_list variable_storage;
+
+ /** List of ir_to_mesa_instruction */
+ exec_list instructions;
+
+ ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0);
+
+ ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1);
+
+ ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1,
+ ir_to_mesa_src_reg src2);
+
+ void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0);
+
+ /* talloc context (the ) */
+ void *ctx;
+};
+
+ir_to_mesa_src_reg ir_to_mesa_undef = {
+ PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
+};
+
+ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
+ PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
+};
+
+ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
+ PROGRAM_ADDRESS, 0, WRITEMASK_X
+};
+
+static int swizzle_for_size(int size)
+{
+ int size_swizzles[4] = {
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
+ };
+
+ return size_swizzles[size - 1];
+}
+
+/* This list should match up with builtin_variables.h */
+static const struct {
+ const char *name;
+ int file;
+ int index;
+} builtin_var_to_mesa_reg[] = {
+ /* core_vs */
+ {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS},
+ {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ},
+
+ /* core_fs */
+ {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS},
+ {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE},
+ {"gl_FragColor", PROGRAM_OUTPUT, FRAG_ATTRIB_COL0},
+ {"gl_FragDepth", PROGRAM_UNDEFINED, FRAG_ATTRIB_WPOS}, /* FINISHME: WPOS.z */
+
+ /* 110_deprecated_fs */
+ {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
+ {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1},
+ {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC},
+ {"gl_TexCoord", PROGRAM_INPUT, FRAG_ATTRIB_TEX0}, /* array */
+
+ /* 110_deprecated_vs */
+ {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS},
+ {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL},
+ {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0},
+ {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1},
+ {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0},
+ {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1},
+ {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2},
+ {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3},
+ {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4},
+ {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5},
+ {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6},
+ {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7},
+ {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */
+ {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC},
+ /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
+ {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0},
+ {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0},
+ {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1},
+ {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1},
+ {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC},
+
+ /* 130_vs */
+ /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
+
+ {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */
+};
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1,
+ ir_to_mesa_src_reg src2)
+{
+ ir_to_mesa_instruction *inst = new(ctx) ir_to_mesa_instruction();
+
+ inst->op = op;
+ inst->dst_reg = dst;
+ inst->src_reg[0] = src0;
+ inst->src_reg[1] = src1;
+ inst->src_reg[2] = src2;
+ inst->ir = ir;
+
+ this->instructions.push_tail(inst);
+
+ return inst;
+}
+
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1)
+{
+ return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0)
+{
+ return ir_to_mesa_emit_op3(ir, op, dst,
+ src0, ir_to_mesa_undef, ir_to_mesa_undef);
+}
+
+inline ir_to_mesa_dst_reg
+ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
+{
+ ir_to_mesa_dst_reg dst_reg;
+
+ dst_reg.file = reg.file;
+ dst_reg.index = reg.index;
+ dst_reg.writemask = WRITEMASK_XYZW;
+
+ return dst_reg;
+}
+
+/**
+ * Emits Mesa scalar opcodes to produce unique answers across channels.
+ *
+ * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X
+ * channel determines the result across all channels. So to do a vec4
+ * of this operation, we want to emit a scalar per source channel used
+ * to produce dest channels.
+ */
+void
+ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0)
+{
+ int i, j;
+ int done_mask = ~dst.writemask;
+
+ /* Mesa RCP is a scalar operation splatting results to all channels,
+ * like ARB_fp/vp. So emit as many RCPs as necessary to cover our
+ * dst channels.
+ */
+ for (i = 0; i < 4; i++) {
+ int this_mask = (1 << i);
+ ir_to_mesa_instruction *inst;
+ ir_to_mesa_src_reg src = src0;
+
+ if (done_mask & this_mask)
+ continue;
+
+ int src_swiz = GET_SWZ(src.swizzle, i);
+ for (j = i + 1; j < 4; j++) {
+ if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) {
+ this_mask |= (1 << j);
+ }
+ }
+ src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz,
+ src_swiz, src_swiz);
+
+ inst = ir_to_mesa_emit_op1(ir, op,
+ dst,
+ src);
+ inst->dst_reg.writemask = this_mask;
+ done_mask |= this_mask;
+ }
+}
+
+struct ir_to_mesa_src_reg
+ir_to_mesa_visitor::src_reg_for_float(float val)
+{
+ ir_to_mesa_src_reg src_reg;
+
+ /* FINISHME: This will end up being _mesa_add_unnamed_constant,
+ * which handles sharing values and sharing channels of vec4
+ * constants for small values.
+ */
+ /* FINISHME: Do something with the constant values for now.
+ */
+ (void)val;
+ src_reg.file = PROGRAM_CONSTANT;
+ src_reg.index = this->next_constant++;
+ src_reg.swizzle = SWIZZLE_NOOP;
+
+ return src_reg;
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results. (not SSA -- variable assignments will reuse
+ * storage). Actual register allocation for the Mesa VM occurs in a
+ * pass over the Mesa IR later.
+ */
+ir_to_mesa_src_reg
+ir_to_mesa_visitor::get_temp(const glsl_type *type)
+{
+ ir_to_mesa_src_reg src_reg;
+ int swizzle[4];
+ int i;
+
+ assert(!type->is_array());
+
+ src_reg.file = PROGRAM_TEMPORARY;
+ src_reg.index = type->matrix_columns;
+ src_reg.reladdr = false;
+
+ for (i = 0; i < type->vector_elements; i++)
+ swizzle[i] = i;
+ for (; i < 4; i++)
+ swizzle[i] = type->vector_elements - 1;
+ src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
+ swizzle[2], swizzle[3]);
+
+ return src_reg;
+}
+
+static int
+type_size(const struct glsl_type *type)
+{
+ unsigned int i;
+ int size;
+
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ if (type->is_matrix()) {
+ return 4; /* FINISHME: Not all matrices are 4x4. */
+ } else {
+ /* Regardless of size of vector, it gets a vec4. This is bad
+ * packing for things like floats, but otherwise arrays become a
+ * mess. Hopefully a later pass over the code can pack scalars
+ * down if appropriate.
+ */
+ return 1;
+ }
+ case GLSL_TYPE_ARRAY:
+ return type_size(type->fields.array) * type->length;
+ case GLSL_TYPE_STRUCT:
+ size = 0;
+ for (i = 0; i < type->length; i++) {
+ size += type_size(type->fields.structure[i].type);
+ }
+ return size;
+ default:
+ assert(0);
+ }
+}
+
+temp_entry *
+ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
+{
+
+ temp_entry *entry;
+
+ foreach_iter(exec_list_iterator, iter, this->variable_storage) {
+ entry = (temp_entry *)iter.get();
+
+ if (entry->var == var)
+ return entry;
+ }
+
+ return NULL;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_variable *ir)
+{
+ (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop *ir)
+{
+ assert(!ir->from);
+ assert(!ir->to);
+ assert(!ir->increment);
+ assert(!ir->counter);
+
+ ir_to_mesa_emit_op1(NULL, OPCODE_BGNLOOP,
+ ir_to_mesa_undef_dst, ir_to_mesa_undef);
+
+ visit_exec_list(&ir->body_instructions, this);
+
+ ir_to_mesa_emit_op1(NULL, OPCODE_ENDLOOP,
+ ir_to_mesa_undef_dst, ir_to_mesa_undef);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop_jump *ir)
+{
+ switch (ir->mode) {
+ case ir_loop_jump::jump_break:
+ ir_to_mesa_emit_op1(NULL, OPCODE_BRK,
+ ir_to_mesa_undef_dst, ir_to_mesa_undef);
+ break;
+ case ir_loop_jump::jump_continue:
+ ir_to_mesa_emit_op1(NULL, OPCODE_CONT,
+ ir_to_mesa_undef_dst, ir_to_mesa_undef);
+ break;
+ }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_function_signature *ir)
+{
+ assert(0);
+ (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_function *ir)
+{
+ /* Ignore function bodies other than main() -- we shouldn't see calls to
+ * them since they should all be inlined before we get to ir_to_mesa.
+ */
+ if (strcmp(ir->name, "main") == 0) {
+ const ir_function_signature *sig;
+ exec_list empty;
+
+ sig = ir->matching_signature(&empty);
+
+ assert(sig);
+
+ foreach_iter(exec_list_iterator, iter, sig->body) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+
+ ir->accept(this);
+ }
+ }
+}
+
+void
+ir_to_mesa_visitor::visit(ir_expression *ir)
+{
+ unsigned int operand;
+ struct ir_to_mesa_src_reg op[2];
+ struct ir_to_mesa_src_reg result_src;
+ struct ir_to_mesa_dst_reg result_dst;
+ const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
+ const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
+ const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ this->result.file = PROGRAM_UNDEFINED;
+ ir->operands[operand]->accept(this);
+ if (this->result.file == PROGRAM_UNDEFINED) {
+ ir_print_visitor v;
+ printf("Failed to get tree for expression operand:\n");
+ ir->operands[operand]->accept(&v);
+ exit(1);
+ }
+ op[operand] = this->result;
+
+ /* Only expression implemented for matrices yet */
+ assert(!ir->operands[operand]->type->is_matrix() ||
+ ir->operation == ir_binop_mul);
+ }
+
+ this->result.file = PROGRAM_UNDEFINED;
+
+ /* Storage for our result. Ideally for an assignment we'd be using
+ * the actual storage for the result here, instead.
+ */
+ result_src = get_temp(ir->type);
+ /* convenience for the emit functions below. */
+ result_dst = ir_to_mesa_dst_reg_from_src(result_src);
+ /* Limit writes to the channels that will be used by result_src later.
+ * This does limit this temp's use as a temporary for multi-instruction
+ * sequences.
+ */
+ result_dst.writemask = (1 << ir->type->vector_elements) - 1;
+
+ switch (ir->operation) {
+ case ir_unop_logic_not:
+ ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
+ op[0], src_reg_for_float(0.0));
+ break;
+ case ir_unop_neg:
+ op[0].negate = ~op[0].negate;
+ result_src = op[0];
+ break;
+ case ir_unop_exp:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_EXP, result_dst, op[0]);
+ break;
+ case ir_unop_exp2:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
+ break;
+ case ir_unop_log:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
+ break;
+ case ir_unop_log2:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
+ break;
+ case ir_unop_sin:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
+ break;
+ case ir_unop_cos:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
+ break;
+ case ir_binop_add:
+ ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_sub:
+ ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_mul:
+ if (ir->operands[0]->type->is_matrix() &&
+ !ir->operands[1]->type->is_matrix()) {
+ if (ir->operands[0]->type->is_scalar()) {
+ ir_to_mesa_dst_reg dst_column = result_dst;
+ ir_to_mesa_src_reg src_column = op[0];
+ for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+ dst_column, src_column, op[1]);
+ dst_column.index++;
+ src_column.index++;
+ }
+ } else {
+ ir_to_mesa_dst_reg dst_chan = result_dst;
+ ir_to_mesa_src_reg src_column = op[0];
+ ir_to_mesa_src_reg src_chan = op[1];
+ for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
+ dst_chan.writemask = (1 << i);
+ src_chan.swizzle = MAKE_SWIZZLE4(i, i, i, i);
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+ dst_chan, src_column, src_chan);
+ src_column.index++;
+ }
+ }
+ } else {
+ assert(!ir->operands[0]->type->is_matrix());
+ assert(!ir->operands[1]->type->is_matrix());
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
+ }
+ break;
+ case ir_binop_div:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[1]);
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], result_src);
+ break;
+
+ case ir_binop_less:
+ ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_greater:
+ ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_lequal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_gequal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_equal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_logic_xor:
+ case ir_binop_nequal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+ break;
+
+ case ir_binop_logic_or:
+ /* This could be a saturated add and skip the SNE. */
+ ir_to_mesa_emit_op2(ir, OPCODE_ADD,
+ result_dst,
+ op[0], op[1]);
+
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+ result_dst,
+ result_src, src_reg_for_float(0.0));
+ break;
+
+ case ir_binop_logic_and:
+ /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+ result_dst,
+ op[0], op[1]);
+ break;
+
+ case ir_binop_dot:
+ if (ir->operands[0]->type == vec4_type) {
+ assert(ir->operands[1]->type == vec4_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP4,
+ result_dst,
+ op[0], op[1]);
+ } else if (ir->operands[0]->type == vec3_type) {
+ assert(ir->operands[1]->type == vec3_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP3,
+ result_dst,
+ op[0], op[1]);
+ } else if (ir->operands[0]->type == vec2_type) {
+ assert(ir->operands[1]->type == vec2_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP2,
+ result_dst,
+ op[0], op[1]);
+ }
+ break;
+ case ir_unop_sqrt:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
+ ir_to_mesa_emit_op1(ir, OPCODE_RCP, result_dst, result_src);
+ break;
+ case ir_unop_rsq:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
+ break;
+ case ir_unop_i2f:
+ /* Mesa IR lacks types, ints are stored as truncated floats. */
+ result_src = op[0];
+ break;
+ case ir_unop_f2i:
+ ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
+ break;
+ case ir_unop_f2b:
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
+ result_src, src_reg_for_float(0.0));
+ break;
+ case ir_unop_trunc:
+ ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
+ break;
+ case ir_unop_ceil:
+ op[0].negate = ~op[0].negate;
+ ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
+ result_src.negate = ~result_src.negate;
+ break;
+ case ir_unop_floor:
+ ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
+ break;
+ case ir_binop_min:
+ ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_max:
+ ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
+ break;
+ default:
+ ir_print_visitor v;
+ printf("Failed to get tree for expression:\n");
+ ir->accept(&v);
+ exit(1);
+ break;
+ }
+
+ this->result = result_src;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_swizzle *ir)
+{
+ ir_to_mesa_src_reg src_reg;
+ int i;
+ int swizzle[4];
+
+ /* Note that this is only swizzles in expressions, not those on the left
+ * hand side of an assignment, which do write masking. See ir_assignment
+ * for that.
+ */
+
+ ir->val->accept(this);
+ src_reg = this->result;
+ assert(src_reg.file != PROGRAM_UNDEFINED);
+
+ for (i = 0; i < 4; i++) {
+ if (i < ir->type->vector_elements) {
+ switch (i) {
+ case 0:
+ swizzle[i] = ir->mask.x;
+ break;
+ case 1:
+ swizzle[i] = ir->mask.y;
+ break;
+ case 2:
+ swizzle[i] = ir->mask.z;
+ break;
+ case 3:
+ swizzle[i] = ir->mask.w;
+ break;
+ }
+ } else {
+ /* If the type is smaller than a vec4, replicate the last
+ * channel out.
+ */
+ swizzle[i] = ir->type->vector_elements - 1;
+ }
+ }
+
+ src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
+ swizzle[1],
+ swizzle[2],
+ swizzle[3]);
+
+ this->result = src_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
+{
+ ir_to_mesa_src_reg src_reg;
+ temp_entry *entry = find_variable_storage(ir->var);
+ unsigned int i;
+ bool var_in;
+
+ if (!entry) {
+ switch (ir->var->mode) {
+ case ir_var_uniform:
+ entry = new(ctx) temp_entry(ir->var, PROGRAM_UNIFORM,
+ this->next_uniform);
+ this->variable_storage.push_tail(entry);
+
+ this->next_uniform += type_size(ir->var->type);
+ break;
+ case ir_var_in:
+ case ir_var_out:
+ case ir_var_inout:
+ var_in = (ir->var->mode == ir_var_in ||
+ ir->var->mode == ir_var_inout);
+
+ for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
+ bool in = builtin_var_to_mesa_reg[i].file == PROGRAM_INPUT;
+
+ if (strcmp(ir->var->name, builtin_var_to_mesa_reg[i].name) == 0 &&
+ !(var_in ^ in))
+ break;
+ }
+ if (i == ARRAY_SIZE(builtin_var_to_mesa_reg)) {
+ printf("Failed to find builtin for %s variable %s\n",
+ var_in ? "in" : "out",
+ ir->var->name);
+ abort();
+ }
+ entry = new(ctx) temp_entry(ir->var,
+ builtin_var_to_mesa_reg[i].file,
+ builtin_var_to_mesa_reg[i].index);
+ break;
+ case ir_var_auto:
+ entry = new(ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
+ this->next_temp);
+ this->variable_storage.push_tail(entry);
+
+ next_temp += type_size(ir->var->type);
+ break;
+ }
+
+ if (!entry) {
+ printf("Failed to make storage for %s\n", ir->var->name);
+ exit(1);
+ }
+ }
+
+ src_reg.file = entry->file;
+ src_reg.index = entry->index;
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
+ src_reg.reladdr = false;
+ src_reg.negate = 0;
+
+ this->result = src_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_array *ir)
+{
+ ir_constant *index;
+ ir_to_mesa_src_reg src_reg;
+
+ index = ir->array_index->constant_expression_value();
+
+ /* By the time we make it to this stage, matrices should be broken down
+ * to vectors.
+ */
+ assert(!ir->type->is_matrix());
+
+ ir->array->accept(this);
+ src_reg = this->result;
+
+ if (src_reg.file == PROGRAM_INPUT ||
+ src_reg.file == PROGRAM_OUTPUT) {
+ assert(index); /* FINISHME: Handle variable indexing of builtins. */
+
+ src_reg.index += index->value.i[0];
+ } else {
+ if (index) {
+ src_reg.index += index->value.i[0];
+ } else {
+ ir_to_mesa_src_reg array_base = this->result;
+ /* Variable index array dereference. It eats the "vec4" of the
+ * base of the array and an index that offsets the Mesa register
+ * index.
+ */
+ ir->array_index->accept(this);
+
+ /* FINISHME: This doesn't work when we're trying to do the LHS
+ * of an assignment.
+ */
+ src_reg.reladdr = true;
+ ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
+ this->result);
+
+ this->result = get_temp(ir->type);
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV,
+ ir_to_mesa_dst_reg_from_src(this->result),
+ src_reg);
+ }
+ }
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
+
+ this->result = src_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_record *ir)
+{
+ unsigned int i;
+ const glsl_type *struct_type = ir->record->type;
+ int offset = 0;
+
+ ir->record->accept(this);
+
+ for (i = 0; i < struct_type->length; i++) {
+ if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
+ break;
+ offset += type_size(struct_type->fields.structure[i].type);
+ }
+ this->result.index += offset;
+}
+
+/**
+ * We want to be careful in assignment setup to hit the actual storage
+ * instead of potentially using a temporary like we might with the
+ * ir_dereference handler.
+ *
+ * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
+ * should only see potentially one variable array index of a vector,
+ * and one swizzle, before getting to actual vec4 storage. So handle
+ * those, then go use ir_dereference to handle the rest.
+ */
+static struct ir_to_mesa_dst_reg
+get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
+{
+ struct ir_to_mesa_dst_reg dst_reg;
+ ir_dereference *deref;
+ ir_swizzle *swiz;
+
+ /* Use the rvalue deref handler for the most part. We'll ignore
+ * swizzles in it and write swizzles using writemask, though.
+ */
+ ir->accept(v);
+ dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
+
+ if ((deref = ir->as_dereference())) {
+ ir_dereference_array *deref_array = ir->as_dereference_array();
+ assert(!deref_array || deref_array->array->type->is_array());
+
+ ir->accept(v);
+ } else if ((swiz = ir->as_swizzle())) {
+ dst_reg.writemask = 0;
+ if (swiz->mask.num_components >= 1)
+ dst_reg.writemask |= (1 << swiz->mask.x);
+ if (swiz->mask.num_components >= 2)
+ dst_reg.writemask |= (1 << swiz->mask.y);
+ if (swiz->mask.num_components >= 3)
+ dst_reg.writemask |= (1 << swiz->mask.z);
+ if (swiz->mask.num_components >= 4)
+ dst_reg.writemask |= (1 << swiz->mask.w);
+ }
+
+ return dst_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_assignment *ir)
+{
+ struct ir_to_mesa_dst_reg l;
+ struct ir_to_mesa_src_reg r;
+
+ assert(!ir->lhs->type->is_matrix());
+ assert(!ir->lhs->type->is_array());
+ assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
+
+ l = get_assignment_lhs(ir->lhs, this);
+
+ ir->rhs->accept(this);
+ r = this->result;
+ assert(l.file != PROGRAM_UNDEFINED);
+ assert(r.file != PROGRAM_UNDEFINED);
+
+ if (ir->condition) {
+ ir_constant *condition_constant;
+
+ condition_constant = ir->condition->constant_expression_value();
+
+ assert(condition_constant && condition_constant->value.b[0]);
+ }
+
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_constant *ir)
+{
+ ir_to_mesa_src_reg src_reg;
+
+ assert(ir->type->base_type == GLSL_TYPE_FLOAT ||
+ ir->type->base_type == GLSL_TYPE_UINT ||
+ ir->type->base_type == GLSL_TYPE_INT ||
+ ir->type->base_type == GLSL_TYPE_BOOL);
+
+ /* FINISHME: This will end up being _mesa_add_unnamed_constant,
+ * which handles sharing values and sharing channels of vec4
+ * constants for small values.
+ */
+ /* FINISHME: Do something with the constant values for now.
+ */
+ src_reg.file = PROGRAM_CONSTANT;
+ src_reg.index = this->next_constant;
+ src_reg.swizzle = SWIZZLE_NOOP;
+ src_reg.reladdr = false;
+ src_reg.negate = 0;
+
+ this->next_constant += type_size(ir->type);
+
+ this->result = src_reg;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_call *ir)
+{
+ printf("Can't support call to %s\n", ir->callee_name());
+ exit(1);
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_texture *ir)
+{
+ assert(0);
+
+ ir->coordinate->accept(this);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_return *ir)
+{
+ assert(0);
+
+ ir->get_value()->accept(this);
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_if *ir)
+{
+ ir_to_mesa_instruction *if_inst, *else_inst = NULL;
+
+ ir->condition->accept(this);
+ assert(this->result.file != PROGRAM_UNDEFINED);
+
+ if_inst = ir_to_mesa_emit_op1(ir->condition,
+ OPCODE_IF, ir_to_mesa_undef_dst,
+ this->result);
+
+ this->instructions.push_tail(if_inst);
+
+ visit_exec_list(&ir->then_instructions, this);
+
+ if (!ir->else_instructions.is_empty()) {
+ else_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ELSE,
+ ir_to_mesa_undef_dst,
+ ir_to_mesa_undef);
+ visit_exec_list(&ir->then_instructions, this);
+ }
+
+ if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
+ ir_to_mesa_undef_dst, ir_to_mesa_undef);
+}
+
+ir_to_mesa_visitor::ir_to_mesa_visitor()
+{
+ result.file = PROGRAM_UNDEFINED;
+ next_temp = 1;
+ next_constant = 0;
+ next_uniform = 0;
+}
+
+static struct prog_src_register
+mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
+{
+ struct prog_src_register mesa_reg;
+
+ mesa_reg.File = reg.file;
+ assert(reg.index < (1 << INST_INDEX_BITS) - 1);
+ mesa_reg.Index = reg.index;
+ mesa_reg.Swizzle = reg.swizzle;
+ mesa_reg.RelAddr = reg.reladdr;
+
+ return mesa_reg;
+}
+
+static void
+set_branchtargets(struct prog_instruction *mesa_instructions,
+ int num_instructions)
+{
+ int if_count = 0, loop_count;
+ int *if_stack, *loop_stack;
+ int if_stack_pos = 0, loop_stack_pos = 0;
+ int i, j;
+
+ for (i = 0; i < num_instructions; i++) {
+ switch (mesa_instructions[i].Opcode) {
+ case OPCODE_IF:
+ if_count++;
+ break;
+ case OPCODE_BGNLOOP:
+ loop_count++;
+ break;
+ case OPCODE_BRK:
+ case OPCODE_CONT:
+ mesa_instructions[i].BranchTarget = -1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if_stack = (int *)calloc(if_count, sizeof(*if_stack));
+ loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
+
+ for (i = 0; i < num_instructions; i++) {
+ switch (mesa_instructions[i].Opcode) {
+ case OPCODE_IF:
+ if_stack[if_stack_pos] = i;
+ if_stack_pos++;
+ break;
+ case OPCODE_ELSE:
+ mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+ if_stack[if_stack_pos - 1] = i;
+ break;
+ case OPCODE_ENDIF:
+ mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+ if_stack_pos--;
+ break;
+ case OPCODE_BGNLOOP:
+ loop_stack[loop_stack_pos] = i;
+ loop_stack_pos++;
+ break;
+ case OPCODE_ENDLOOP:
+ loop_stack_pos--;
+ /* Rewrite any breaks/conts at this nesting level (haven't
+ * already had a BranchTarget assigned) to point to the end
+ * of the loop.
+ */
+ for (j = loop_stack[loop_stack_pos]; j < i; j++) {
+ if (mesa_instructions[j].Opcode == OPCODE_BRK ||
+ mesa_instructions[j].Opcode == OPCODE_CONT) {
+ if (mesa_instructions[j].BranchTarget == -1) {
+ mesa_instructions[j].BranchTarget = i;
+ }
+ }
+ }
+ /* The loop ends point at each other. */
+ mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
+ mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
+ default:
+ break;
+ }
+ }
+
+ free(if_stack);
+}
+
+static void
+print_program(struct prog_instruction *mesa_instructions,
+ ir_instruction **mesa_instruction_annotation,
+ int num_instructions)
+{
+ ir_instruction *last_ir = NULL;
+ int i;
+
+ for (i = 0; i < num_instructions; i++) {
+ struct prog_instruction *mesa_inst = mesa_instructions + i;
+ ir_instruction *ir = mesa_instruction_annotation[i];
+
+ if (last_ir != ir && ir) {
+ ir_print_visitor print;
+ ir->accept(&print);
+ printf("\n");
+ last_ir = ir;
+ }
+
+ _mesa_print_instruction(mesa_inst);
+ }
+}
+
+void
+do_ir_to_mesa(exec_list *instructions)
+{
+ ir_to_mesa_visitor v;
+ struct prog_instruction *mesa_instructions, *mesa_inst;
+ ir_instruction **mesa_instruction_annotation;
+ int i;
+
+ v.ctx = talloc_new(NULL);
+ visit_exec_list(instructions, &v);
+
+ int num_instructions = 0;
+ foreach_iter(exec_list_iterator, iter, v.instructions) {
+ num_instructions++;
+ }
+
+ mesa_instructions =
+ (struct prog_instruction *)calloc(num_instructions,
+ sizeof(*mesa_instructions));
+ mesa_instruction_annotation =
+ (ir_instruction **)calloc(num_instructions,
+ sizeof(*mesa_instruction_annotation));
+
+ mesa_inst = mesa_instructions;
+ i = 0;
+ foreach_iter(exec_list_iterator, iter, v.instructions) {
+ ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
+
+ mesa_inst->Opcode = inst->op;
+ mesa_inst->DstReg.File = inst->dst_reg.file;
+ mesa_inst->DstReg.Index = inst->dst_reg.index;
+ mesa_inst->DstReg.CondMask = COND_TR;
+ mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
+ mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
+ mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
+ mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
+ mesa_instruction_annotation[i] = inst->ir;
+
+ mesa_inst++;
+ i++;
+ }
+
+ set_branchtargets(mesa_instructions, num_instructions);
+ print_program(mesa_instructions, mesa_instruction_annotation, num_instructions);
+
+ free(mesa_instruction_annotation);
+ talloc_free(v.ctx);
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_validate.cpp
+ *
+ * Attempts to verify that various invariants of the IR tree are true.
+ *
+ * In particular, at the moment it makes sure that no single
+ * ir_instruction node except for ir_variable appears multiple times
+ * in the ir tree. ir_variable does appear multiple times: Once as a
+ * declaration in an exec_list, and multiple times as the endpoint of
+ * a dereference chain.
+ */
+
+#include <inttypes.h>
+#include "ir.h"
+#include "ir_hierarchical_visitor.h"
+#include "hash_table.h"
+
+static unsigned int hash_func(const void *key)
+{
+ return (unsigned int)(uintptr_t)key;
+}
+
+static int hash_compare_func(const void *key1, const void *key2)
+{
+ return key1 == key2 ? 0 : 1;
+}
+
+
+class ir_validate : public ir_hierarchical_visitor {
+public:
+ ir_validate()
+ {
+ this->ht = hash_table_ctor(0, hash_func, hash_compare_func);
+
+ this->callback = ir_validate::validate_ir;
+ this->data = ht;
+ }
+
+ ~ir_validate()
+ {
+ hash_table_dtor(this->ht);
+ }
+
+ virtual ir_visitor_status visit(ir_variable *v);
+
+ static void validate_ir(ir_instruction *ir, void *data);
+
+ struct hash_table *ht;
+};
+
+ir_visitor_status
+ir_validate::visit(ir_variable *ir)
+{
+ /* An ir_variable is the one thing that can (and will) appear multiple times
+ * in an IR tree.
+ */
+ (void) ir;
+ return visit_continue;
+}
+
+void
+ir_validate::validate_ir(ir_instruction *ir, void *data)
+{
+ struct hash_table *ht = (struct hash_table *) data;
+
+ if (hash_table_find(ht, ir)) {
+ printf("Instruction node present twice in ir tree:\n");
+ ir->print();
+ printf("\n");
+ abort();
+ }
+ hash_table_insert(ht, ir, ir);
+}
+
+void
+validate_ir_tree(exec_list *instructions)
+{
+ ir_validate v;
+
+ v.run(instructions);
+}
--- /dev/null
+/*
+ * 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 "ir.h"
+#include "glsl_parser_extras.h"
+#include "glsl_symbol_table.h"
+#include "builtin_variables.h"
+
+#ifndef Elements
+#define Elements(x) (sizeof(x)/sizeof(*(x)))
+#endif
+
+static ir_variable *
+add_variable(const char *name, enum ir_variable_mode mode, int slot,
+ const glsl_type *type, exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ ir_variable *var = new(symtab) ir_variable(type, name);
+
+ var->mode = mode;
+ switch (var->mode) {
+ case ir_var_in:
+ var->shader_in = true;
+ var->read_only = true;
+ break;
+ case ir_var_inout:
+ var->shader_in = true;
+ var->shader_out = true;
+ break;
+ case ir_var_out:
+ var->shader_out = true;
+ break;
+ case ir_var_uniform:
+ var->shader_in = true;
+ var->read_only = true;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ var->location = slot;
+
+ /* Once the variable is created an initialized, add it to the symbol table
+ * and add the declaration to the IR stream.
+ */
+ instructions->push_tail(var);
+
+ symtab->add_variable(var->name, var);
+ return var;
+}
+
+
+static void
+add_builtin_variable(const builtin_variable *proto, exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ /* Create a new variable declaration from the description supplied by
+ * the caller.
+ */
+ const glsl_type *const type = symtab->get_type(proto->type);
+
+ assert(type != NULL);
+
+ add_variable(proto->name, proto->mode, proto->slot, type, instructions,
+ symtab);
+}
+
+
+static void
+generate_110_uniforms(exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ for (unsigned i = 0
+ ; i < Elements(builtin_110_deprecated_uniforms)
+ ; i++) {
+ add_builtin_variable(& builtin_110_deprecated_uniforms[i],
+ instructions, symtab);
+ }
+
+ /* FINISHME: The size of this array is implementation dependent based on the
+ * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports
+ * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4
+ * FINISHME: for now.
+ */
+ const glsl_type *const mat4_array_type =
+ glsl_type::get_array_instance(symtab, glsl_type::mat4_type, 4);
+
+ add_variable("gl_TextureMatrix", ir_var_uniform, -1, mat4_array_type,
+ instructions, symtab);
+
+ /* FINISHME: Add support for gl_DepthRangeParameters */
+ /* FINISHME: Add support for gl_ClipPlane[] */
+ /* FINISHME: Add support for gl_PointParameters */
+
+ /* FINISHME: Add support for gl_MaterialParameters
+ * FINISHME: (glFrontMaterial, glBackMaterial)
+ */
+
+ /* FINISHME: The size of this array is implementation dependent based on the
+ * FINISHME: value of GL_MAX_TEXTURE_LIGHTS. GL_MAX_TEXTURE_LIGHTS must be
+ * FINISHME: at least 8, so hard-code 8 for now.
+ */
+ const glsl_type *const light_source_array_type =
+ glsl_type::get_array_instance(symtab,
+ symtab->get_type("gl_LightSourceParameters"), 8);
+
+ add_variable("gl_LightSource", ir_var_uniform, -1, light_source_array_type,
+ instructions, symtab);
+
+ /* FINISHME: Add support for gl_LightModel */
+ /* FINISHME: Add support for gl_FrontLightProduct[], gl_BackLightProduct[] */
+ /* FINISHME: Add support for gl_TextureEnvColor[] */
+ /* FINISHME: Add support for gl_ObjectPlane*[], gl_EyePlane*[] */
+ /* FINISHME: Add support for gl_Fog */
+}
+
+static void
+generate_110_vs_variables(exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
+ add_builtin_variable(& builtin_core_vs_variables[i],
+ instructions, symtab);
+ }
+
+ for (unsigned i = 0
+ ; i < Elements(builtin_110_deprecated_vs_variables)
+ ; i++) {
+ add_builtin_variable(& builtin_110_deprecated_vs_variables[i],
+ instructions, symtab);
+ }
+ generate_110_uniforms(instructions, symtab);
+
+ /* FINISHME: The size of this array is implementation dependent based on the
+ * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports
+ * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4
+ * FINISHME: for now.
+ */
+ const glsl_type *const vec4_array_type =
+ glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4);
+
+ add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type,
+ instructions, symtab);
+}
+
+
+static void
+generate_120_vs_variables(exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ /* GLSL version 1.20 did not add any built-in variables in the vertex
+ * shader.
+ */
+ generate_110_vs_variables(instructions, symtab);
+}
+
+
+static void
+generate_130_vs_variables(exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ void *ctx = symtab;
+ generate_120_vs_variables(instructions, symtab);
+
+ for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) {
+ add_builtin_variable(& builtin_130_vs_variables[i],
+ instructions, symtab);
+ }
+
+ /* FINISHME: The size of this array is implementation dependent based on
+ * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
+ */
+ const glsl_type *const clip_distance_array_type =
+ glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
+
+ /* FINISHME: gl_ClipDistance needs a real location assigned. */
+ add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type,
+ instructions, symtab);
+
+}
+
+
+static void
+initialize_vs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+
+ switch (state->language_version) {
+ case 110:
+ generate_110_vs_variables(instructions, state->symbols);
+ break;
+ case 120:
+ generate_120_vs_variables(instructions, state->symbols);
+ break;
+ case 130:
+ generate_130_vs_variables(instructions, state->symbols);
+ break;
+ }
+}
+
+static void
+generate_110_fs_variables(exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
+ add_builtin_variable(& builtin_core_fs_variables[i],
+ instructions, symtab);
+ }
+
+ for (unsigned i = 0
+ ; i < Elements(builtin_110_deprecated_fs_variables)
+ ; i++) {
+ add_builtin_variable(& builtin_110_deprecated_fs_variables[i],
+ instructions, symtab);
+ }
+ generate_110_uniforms(instructions, symtab);
+
+ /* FINISHME: The size of this array is implementation dependent based on the
+ * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports
+ * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4
+ * FINISHME: for now.
+ */
+ const glsl_type *const vec4_array_type =
+ glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4);
+
+ add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type,
+ instructions, symtab);
+}
+
+
+static void
+generate_ARB_draw_buffers_fs_variables(exec_list *instructions,
+ glsl_symbol_table *symtab, bool warn)
+{
+ /* FINISHME: The size of this array is implementation dependent based on the
+ * FINISHME: value of GL_MAX_DRAW_BUFFERS. GL_MAX_DRAW_BUFFERS must be
+ * FINISHME: at least 1, so hard-code 1 for now.
+ */
+ const glsl_type *const vec4_array_type =
+ glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 1);
+
+ ir_variable *const fd =
+ add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0,
+ vec4_array_type, instructions, symtab);
+
+ if (warn)
+ fd->warn_extension = "GL_ARB_draw_buffers";
+}
+
+
+static void
+generate_120_fs_variables(exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ generate_110_fs_variables(instructions, symtab);
+ generate_ARB_draw_buffers_fs_variables(instructions, symtab, false);
+}
+
+static void
+generate_130_fs_variables(exec_list *instructions,
+ glsl_symbol_table *symtab)
+{
+ void *ctx = symtab;
+ generate_120_fs_variables(instructions, symtab);
+
+ /* FINISHME: The size of this array is implementation dependent based on
+ * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
+ */
+ const glsl_type *const clip_distance_array_type =
+ glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
+
+ /* FINISHME: gl_ClipDistance needs a real location assigned. */
+ add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type,
+ instructions, symtab);
+}
+
+static void
+initialize_fs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+
+ switch (state->language_version) {
+ case 110:
+ generate_110_fs_variables(instructions, state->symbols);
+ break;
+ case 120:
+ generate_120_fs_variables(instructions, state->symbols);
+ break;
+ case 130:
+ generate_130_fs_variables(instructions, state->symbols);
+ break;
+ }
+
+
+ /* Since GL_ARB_draw_buffers is included in GLSL 1.20 and later, we
+ * can basically ignore any extension settings for it.
+ */
+ if (state->language_version < 120) {
+ if (state->ARB_draw_buffers_enable) {
+ generate_ARB_draw_buffers_fs_variables(instructions, state->symbols,
+ state->ARB_draw_buffers_warn);
+ }
+ }
+}
+
+void
+_mesa_glsl_initialize_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ switch (state->target) {
+ case vertex_shader:
+ initialize_vs_variables(instructions, state);
+ break;
+ case geometry_shader:
+ break;
+ case fragment_shader:
+ initialize_fs_variables(instructions, state);
+ break;
+ case ir_shader:
+ fprintf(stderr, "ir reader has no builtin variables");
+ exit(1);
+ break;
+ }
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file ir_vec_index_to_swizzle.cpp
+ *
+ * Turns constant indexing into vector types to swizzles. This will
+ * let other swizzle-aware optimization passes catch these constructs,
+ * and codegen backends not have to worry about this case.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+/**
+ * Visitor class for replacing expressions with ir_constant values.
+ */
+
+class ir_vec_index_to_swizzle_visitor : public ir_hierarchical_visitor {
+public:
+ ir_vec_index_to_swizzle_visitor()
+ {
+ progress = false;
+ }
+
+ ir_rvalue *convert_vec_index_to_swizzle(ir_rvalue *val);
+
+ virtual ir_visitor_status visit_enter(ir_expression *);
+ virtual ir_visitor_status visit_enter(ir_swizzle *);
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+ virtual ir_visitor_status visit_enter(ir_return *);
+ virtual ir_visitor_status visit_enter(ir_call *);
+ virtual ir_visitor_status visit_enter(ir_if *);
+
+ bool progress;
+};
+
+ir_rvalue *
+ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir)
+{
+ ir_dereference_array *deref = ir->as_dereference_array();
+ ir_constant *ir_constant;
+
+ if (!deref)
+ return ir;
+
+ if (deref->array->type->is_matrix() || deref->array->type->is_array())
+ return ir;
+
+ assert(deref->array_index->type->base_type == GLSL_TYPE_INT);
+ ir_constant = deref->array_index->constant_expression_value();
+ if (!ir_constant)
+ return ir;
+
+ void *ctx = talloc_parent(ir);
+ this->progress = true;
+ return new(ctx) ir_swizzle(deref->array,
+ ir_constant->value.i[0], 0, 0, 0, 1);
+}
+
+ir_visitor_status
+ir_vec_index_to_swizzle_visitor::visit_enter(ir_expression *ir)
+{
+ unsigned int i;
+
+ for (i = 0; i < ir->get_num_operands(); i++) {
+ ir->operands[i] = convert_vec_index_to_swizzle(ir->operands[i]);
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_swizzle_visitor::visit_enter(ir_swizzle *ir)
+{
+ /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which
+ * the result of indexing a vector is. But maybe at some point we'll end up
+ * using swizzling of scalars for vector construction.
+ */
+ ir->val = convert_vec_index_to_swizzle(ir->val);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir)
+{
+ ir->lhs = convert_vec_index_to_swizzle(ir->lhs);
+ ir->rhs = convert_vec_index_to_swizzle(ir->rhs);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir)
+{
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_rvalue *param = (ir_rvalue *)iter.get();
+ ir_rvalue *new_param = convert_vec_index_to_swizzle(param);
+
+ if (new_param != param) {
+ param->insert_before(new_param);
+ param->remove();
+ }
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_swizzle_visitor::visit_enter(ir_return *ir)
+{
+ if (ir->value) {
+ ir->value = convert_vec_index_to_swizzle(ir->value);
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_swizzle_visitor::visit_enter(ir_if *ir)
+{
+ ir->condition = convert_vec_index_to_swizzle(ir->condition);
+
+ return visit_continue;
+}
+
+bool
+do_vec_index_to_swizzle(exec_list *instructions)
+{
+ ir_vec_index_to_swizzle_visitor v;
+
+ v.run(instructions);
+
+ return false;
+}
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef IR_VISITOR_H
+#define IR_VISITOR_H
+
+/**
+ * Abstract base class of visitors of IR instruction trees
+ */
+class ir_visitor {
+public:
+ virtual ~ir_visitor()
+ {
+ /* empty */
+ }
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(class ir_variable *) = 0;
+ virtual void visit(class ir_function_signature *) = 0;
+ virtual void visit(class ir_function *) = 0;
+ virtual void visit(class ir_expression *) = 0;
+ virtual void visit(class ir_texture *) = 0;
+ virtual void visit(class ir_swizzle *) = 0;
+ virtual void visit(class ir_dereference_variable *) = 0;
+ virtual void visit(class ir_dereference_array *) = 0;
+ virtual void visit(class ir_dereference_record *) = 0;
+ virtual void visit(class ir_assignment *) = 0;
+ virtual void visit(class ir_constant *) = 0;
+ virtual void visit(class ir_call *) = 0;
+ virtual void visit(class ir_return *) = 0;
+ virtual void visit(class ir_if *) = 0;
+ virtual void visit(class ir_loop *) = 0;
+ virtual void visit(class ir_loop_jump *) = 0;
+ /*@}*/
+};
+
+#endif /* IR_VISITOR_H */
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * \file linker.cpp
+ * GLSL linker implementation
+ *
+ * Given a set of shaders that are to be linked to generate a final program,
+ * there are three distinct stages.
+ *
+ * In the first stage shaders are partitioned into groups based on the shader
+ * type. All shaders of a particular type (e.g., vertex shaders) are linked
+ * together.
+ *
+ * - Undefined references in each shader are resolve to definitions in
+ * another shader.
+ * - Types and qualifiers of uniforms, outputs, and global variables defined
+ * in multiple shaders with the same name are verified to be the same.
+ * - Initializers for uniforms and global variables defined
+ * in multiple shaders with the same name are verified to be the same.
+ *
+ * The result, in the terminology of the GLSL spec, is a set of shader
+ * executables for each processing unit.
+ *
+ * After the first stage is complete, a series of semantic checks are performed
+ * on each of the shader executables.
+ *
+ * - Each shader executable must define a \c main function.
+ * - Each vertex shader executable must write to \c gl_Position.
+ * - Each fragment shader executable must write to either \c gl_FragData or
+ * \c gl_FragColor.
+ *
+ * In the final stage individual shader executables are linked to create a
+ * complete exectuable.
+ *
+ * - Types of uniforms defined in multiple shader stages with the same name
+ * are verified to be the same.
+ * - Initializers for uniforms defined in multiple shader stages with the
+ * same name are verified to be the same.
+ * - Types and qualifiers of outputs defined in one stage are verified to
+ * be the same as the types and qualifiers of inputs defined with the same
+ * name in a later stage.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+#include <cstdlib>
+#include <cstdio>
+#include <cstdarg>
+
+extern "C" {
+#include <talloc.h>
+}
+
+#include "main/mtypes.h"
+#include "glsl_symbol_table.h"
+#include "glsl_parser_extras.h"
+#include "ir.h"
+#include "ir_optimization.h"
+#include "program.h"
+#include "hash_table.h"
+
+/**
+ * Visitor that determines whether or not a variable is ever written.
+ */
+class find_assignment_visitor : public ir_hierarchical_visitor {
+public:
+ find_assignment_visitor(const char *name)
+ : name(name), found(false)
+ {
+ /* empty */
+ }
+
+ virtual ir_visitor_status visit_enter(ir_assignment *ir)
+ {
+ ir_variable *const var = ir->lhs->variable_referenced();
+
+ if (strcmp(name, var->name) == 0) {
+ found = true;
+ return visit_stop;
+ }
+
+ return visit_continue_with_parent;
+ }
+
+ bool variable_found()
+ {
+ return found;
+ }
+
+private:
+ const char *name; /**< Find writes to a variable with this name. */
+ bool found; /**< Was a write to the variable found? */
+};
+
+
+void
+linker_error_printf(glsl_program *prog, const char *fmt, ...)
+{
+ va_list ap;
+
+ prog->InfoLog = talloc_strdup_append(prog->InfoLog, "error: ");
+ va_start(ap, fmt);
+ prog->InfoLog = talloc_vasprintf_append(prog->InfoLog, fmt, ap);
+ va_end(ap);
+}
+
+
+void
+invalidate_variable_locations(glsl_shader *sh, enum ir_variable_mode mode,
+ int generic_base)
+{
+ foreach_list(node, &sh->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != (unsigned) mode))
+ continue;
+
+ /* Only assign locations for generic attributes / varyings / etc.
+ */
+ if (var->location >= generic_base)
+ var->location = -1;
+ }
+}
+
+
+/**
+ * Determine the number of attribute slots required for a particular type
+ *
+ * This code is here because it implements the language rules of a specific
+ * GLSL version. Since it's a property of the language and not a property of
+ * types in general, it doesn't really belong in glsl_type.
+ */
+unsigned
+count_attribute_slots(const glsl_type *t)
+{
+ /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "A scalar input counts the same amount against this limit as a vec4,
+ * so applications may want to consider packing groups of four
+ * unrelated float inputs together into a vector to better utilize the
+ * capabilities of the underlying hardware. A matrix input will use up
+ * multiple locations. The number of locations used will equal the
+ * number of columns in the matrix."
+ *
+ * The spec does not explicitly say how arrays are counted. However, it
+ * should be safe to assume the total number of slots consumed by an array
+ * is the number of entries in the array multiplied by the number of slots
+ * consumed by a single element of the array.
+ */
+
+ if (t->is_array())
+ return t->array_size() * count_attribute_slots(t->element_type());
+
+ if (t->is_matrix())
+ return t->matrix_columns;
+
+ return 1;
+}
+
+
+/**
+ * Verify that a vertex shader executable meets all semantic requirements
+ *
+ * \param shader Vertex shader executable to be verified
+ */
+bool
+validate_vertex_shader_executable(struct glsl_program *prog,
+ struct glsl_shader *shader)
+{
+ if (shader == NULL)
+ return true;
+
+ if (!shader->symbols->get_function("main")) {
+ linker_error_printf(prog, "vertex shader lacks `main'\n");
+ return false;
+ }
+
+ find_assignment_visitor find("gl_Position");
+ find.run(&shader->ir);
+ if (!find.variable_found()) {
+ linker_error_printf(prog,
+ "vertex shader does not write to `gl_Position'\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Verify that a fragment shader executable meets all semantic requirements
+ *
+ * \param shader Fragment shader executable to be verified
+ */
+bool
+validate_fragment_shader_executable(struct glsl_program *prog,
+ struct glsl_shader *shader)
+{
+ if (shader == NULL)
+ return true;
+
+ if (!shader->symbols->get_function("main")) {
+ linker_error_printf(prog, "fragment shader lacks `main'\n");
+ return false;
+ }
+
+ find_assignment_visitor frag_color("gl_FragColor");
+ find_assignment_visitor frag_data("gl_FragData");
+
+ frag_color.run(&shader->ir);
+ frag_data.run(&shader->ir);
+
+ if (!frag_color.variable_found() && !frag_data.variable_found()) {
+ linker_error_printf(prog, "fragment shader does not write to "
+ "`gl_FragColor' or `gl_FragData'\n");
+ return false;
+ }
+
+ if (frag_color.variable_found() && frag_data.variable_found()) {
+ linker_error_printf(prog, "fragment shader writes to both "
+ "`gl_FragColor' and `gl_FragData'\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Perform validation of uniforms used across multiple shader stages
+ */
+bool
+cross_validate_uniforms(struct glsl_program *prog)
+{
+ /* Examine all of the uniforms in all of the shaders and cross validate
+ * them.
+ */
+ glsl_symbol_table uniforms;
+ for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+ foreach_list(node, &prog->_LinkedShaders[i]->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != ir_var_uniform))
+ continue;
+
+ /* If a uniform with this name has already been seen, verify that the
+ * new instance has the same type. In addition, if the uniforms have
+ * initializers, the values of the initializers must be the same.
+ */
+ ir_variable *const existing = uniforms.get_variable(var->name);
+ if (existing != NULL) {
+ if (var->type != existing->type) {
+ linker_error_printf(prog, "uniform `%s' declared as type "
+ "`%s' and type `%s'\n",
+ var->name, var->type->name,
+ existing->type->name);
+ return false;
+ }
+
+ if (var->constant_value != NULL) {
+ if (existing->constant_value != NULL) {
+ if (!var->constant_value->has_value(existing->constant_value)) {
+ linker_error_printf(prog, "initializers for uniform "
+ "`%s' have differing values\n",
+ var->name);
+ return false;
+ }
+ } else
+ /* If the first-seen instance of a particular uniform did not
+ * have an initializer but a later instance does, copy the
+ * initializer to the version stored in the symbol table.
+ */
+ existing->constant_value =
+ (ir_constant *)var->constant_value->clone(NULL);
+ }
+ } else
+ uniforms.add_variable(var->name, var);
+ }
+ }
+
+ return true;
+}
+
+
+/**
+ * Validate that outputs from one stage match inputs of another
+ */
+bool
+cross_validate_outputs_to_inputs(struct glsl_program *prog,
+ glsl_shader *producer, glsl_shader *consumer)
+{
+ glsl_symbol_table parameters;
+ /* FINISHME: Figure these out dynamically. */
+ const char *const producer_stage = "vertex";
+ const char *const consumer_stage = "fragment";
+
+ /* Find all shader outputs in the "producer" stage.
+ */
+ foreach_list(node, &producer->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ /* FINISHME: For geometry shaders, this should also look for inout
+ * FINISHME: variables.
+ */
+ if ((var == NULL) || (var->mode != ir_var_out))
+ continue;
+
+ parameters.add_variable(var->name, var);
+ }
+
+
+ /* Find all shader inputs in the "consumer" stage. Any variables that have
+ * matching outputs already in the symbol table must have the same type and
+ * qualifiers.
+ */
+ foreach_list(node, &consumer->ir) {
+ ir_variable *const input = ((ir_instruction *) node)->as_variable();
+
+ /* FINISHME: For geometry shaders, this should also look for inout
+ * FINISHME: variables.
+ */
+ if ((input == NULL) || (input->mode != ir_var_in))
+ continue;
+
+ ir_variable *const output = parameters.get_variable(input->name);
+ if (output != NULL) {
+ /* Check that the types match between stages.
+ */
+ if (input->type != output->type) {
+ linker_error_printf(prog,
+ "%s shader output `%s' delcared as "
+ "type `%s', but %s shader input declared "
+ "as type `%s'\n",
+ producer_stage, output->name,
+ output->type->name,
+ consumer_stage, input->type->name);
+ return false;
+ }
+
+ /* Check that all of the qualifiers match between stages.
+ */
+ if (input->centroid != output->centroid) {
+ linker_error_printf(prog,
+ "%s shader output `%s' %s centroid qualifier, "
+ "but %s shader input %s centroid qualifier\n",
+ producer_stage,
+ output->name,
+ (output->centroid) ? "has" : "lacks",
+ consumer_stage,
+ (input->centroid) ? "has" : "lacks");
+ return false;
+ }
+
+ if (input->invariant != output->invariant) {
+ linker_error_printf(prog,
+ "%s shader output `%s' %s invariant qualifier, "
+ "but %s shader input %s invariant qualifier\n",
+ producer_stage,
+ output->name,
+ (output->invariant) ? "has" : "lacks",
+ consumer_stage,
+ (input->invariant) ? "has" : "lacks");
+ return false;
+ }
+
+ if (input->interpolation != output->interpolation) {
+ linker_error_printf(prog,
+ "%s shader output `%s' specifies %s "
+ "interpolation qualifier, "
+ "but %s shader input specifies %s "
+ "interpolation qualifier\n",
+ producer_stage,
+ output->name,
+ output->interpolation_string(),
+ consumer_stage,
+ input->interpolation_string());
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+struct uniform_node {
+ exec_node link;
+ struct gl_uniform *u;
+ unsigned slots;
+};
+
+void
+assign_uniform_locations(struct glsl_program *prog)
+{
+ /* */
+ exec_list uniforms;
+ unsigned total_uniforms = 0;
+ hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
+ hash_table_string_compare);
+
+ for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+ unsigned next_position = 0;
+
+ foreach_list(node, &prog->_LinkedShaders[i]->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != ir_var_uniform))
+ continue;
+
+ const unsigned vec4_slots = (var->component_slots() + 3) / 4;
+ assert(vec4_slots != 0);
+
+ uniform_node *n = (uniform_node *) hash_table_find(ht, var->name);
+ if (n == NULL) {
+ n = (uniform_node *) calloc(1, sizeof(struct uniform_node));
+ n->u = (gl_uniform *) calloc(vec4_slots, sizeof(struct gl_uniform));
+ n->slots = vec4_slots;
+
+ n->u[0].Name = strdup(var->name);
+ for (unsigned j = 1; j < vec4_slots; j++)
+ n->u[j].Name = n->u[0].Name;
+
+ hash_table_insert(ht, n, n->u[0].Name);
+ uniforms.push_tail(& n->link);
+ total_uniforms += vec4_slots;
+ }
+
+ if (var->constant_value != NULL)
+ for (unsigned j = 0; j < vec4_slots; j++)
+ n->u[j].Initialized = true;
+
+ var->location = next_position;
+
+ for (unsigned j = 0; j < vec4_slots; j++) {
+ switch (prog->_LinkedShaders[i]->Type) {
+ case GL_VERTEX_SHADER:
+ n->u[j].VertPos = next_position;
+ break;
+ case GL_FRAGMENT_SHADER:
+ n->u[j].FragPos = next_position;
+ break;
+ case GL_GEOMETRY_SHADER:
+ /* FINISHME: Support geometry shaders. */
+ assert(prog->_LinkedShaders[i]->Type != GL_GEOMETRY_SHADER);
+ break;
+ }
+
+ next_position++;
+ }
+ }
+ }
+
+ gl_uniform_list *ul = (gl_uniform_list *)
+ calloc(1, sizeof(gl_uniform_list));
+
+ ul->Size = total_uniforms;
+ ul->NumUniforms = total_uniforms;
+ ul->Uniforms = (gl_uniform *) calloc(total_uniforms, sizeof(gl_uniform));
+
+ unsigned idx = 0;
+ uniform_node *next;
+ for (uniform_node *node = (uniform_node *) uniforms.head
+ ; node->link.next != NULL
+ ; node = next) {
+ next = (uniform_node *) node->link.next;
+
+ node->link.remove();
+ memcpy(&ul->Uniforms[idx], node->u, sizeof(gl_uniform) * node->slots);
+ idx += node->slots;
+
+ free(node->u);
+ free(node);
+ }
+
+ hash_table_dtor(ht);
+
+ prog->Uniforms = ul;
+}
+
+
+/**
+ * Find a contiguous set of available bits in a bitmask
+ *
+ * \param used_mask Bits representing used (1) and unused (0) locations
+ * \param needed_count Number of contiguous bits needed.
+ *
+ * \return
+ * Base location of the available bits on success or -1 on failure.
+ */
+int
+find_available_slots(unsigned used_mask, unsigned needed_count)
+{
+ unsigned needed_mask = (1 << needed_count) - 1;
+ const int max_bit_to_test = (8 * sizeof(used_mask)) - needed_count;
+
+ /* The comparison to 32 is redundant, but without it GCC emits "warning:
+ * cannot optimize possibly infinite loops" for the loop below.
+ */
+ if ((needed_count == 0) || (max_bit_to_test < 0) || (max_bit_to_test > 32))
+ return -1;
+
+ for (int i = 0; i <= max_bit_to_test; i++) {
+ if ((needed_mask & ~used_mask) == needed_mask)
+ return i;
+
+ needed_mask <<= 1;
+ }
+
+ return -1;
+}
+
+
+bool
+assign_attribute_locations(glsl_program *prog, unsigned max_attribute_index)
+{
+ /* Mark invalid attribute locations as being used.
+ */
+ unsigned used_locations = (max_attribute_index >= 32)
+ ? ~0 : ~((1 << max_attribute_index) - 1);
+
+ glsl_shader *const sh = prog->_LinkedShaders[0];
+ assert(sh->Type == GL_VERTEX_SHADER);
+
+ /* Operate in a total of four passes.
+ *
+ * 1. Invalidate the location assignments for all vertex shader inputs.
+ *
+ * 2. Assign locations for inputs that have user-defined (via
+ * glBindVertexAttribLocation) locatoins.
+ *
+ * 3. Sort the attributes without assigned locations by number of slots
+ * required in decreasing order. Fragmentation caused by attribute
+ * locations assigned by the application may prevent large attributes
+ * from having enough contiguous space.
+ *
+ * 4. Assign locations to any inputs without assigned locations.
+ */
+
+ invalidate_variable_locations(sh, ir_var_in, VERT_ATTRIB_GENERIC0);
+
+ if (prog->Attributes != NULL) {
+ for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) {
+ ir_variable *const var =
+ sh->symbols->get_variable(prog->Attributes->Parameters[i].Name);
+
+ /* Note: attributes that occupy multiple slots, such as arrays or
+ * matrices, may appear in the attrib array multiple times.
+ */
+ if ((var == NULL) || (var->location != -1))
+ continue;
+
+ /* From page 61 of the OpenGL 4.0 spec:
+ *
+ * "LinkProgram will fail if the attribute bindings assigned by
+ * BindAttribLocation do not leave not enough space to assign a
+ * location for an active matrix attribute or an active attribute
+ * array, both of which require multiple contiguous generic
+ * attributes."
+ *
+ * Previous versions of the spec contain similar language but omit the
+ * bit about attribute arrays.
+ *
+ * Page 61 of the OpenGL 4.0 spec also says:
+ *
+ * "It is possible for an application to bind more than one
+ * attribute name to the same location. This is referred to as
+ * aliasing. This will only work if only one of the aliased
+ * attributes is active in the executable program, or if no path
+ * through the shader consumes more than one attribute of a set
+ * of attributes aliased to the same location. A link error can
+ * occur if the linker determines that every path through the
+ * shader consumes multiple aliased attributes, but
+ * implementations are not required to generate an error in this
+ * case."
+ *
+ * These two paragraphs are either somewhat contradictory, or I don't
+ * fully understand one or both of them.
+ */
+ /* FINISHME: The code as currently written does not support attribute
+ * FINISHME: location aliasing (see comment above).
+ */
+ const int attr = prog->Attributes->Parameters[i].StateIndexes[0];
+ const unsigned slots = count_attribute_slots(var->type);
+
+ /* Mask representing the contiguous slots that will be used by this
+ * attribute.
+ */
+ const unsigned use_mask = (1 << slots) - 1;
+
+ /* Generate a link error if the set of bits requested for this
+ * attribute overlaps any previously allocated bits.
+ */
+ if ((~(use_mask << attr) & used_locations) != used_locations) {
+ linker_error_printf(prog,
+ "insufficient contiguous attribute locations "
+ "available for vertex shader input `%s'",
+ var->name);
+ return false;
+ }
+
+ var->location = VERT_ATTRIB_GENERIC0 + attr;
+ used_locations |= (use_mask << attr);
+ }
+ }
+
+ /* Temporary storage for the set of attributes that need locations assigned.
+ */
+ struct temp_attr {
+ unsigned slots;
+ ir_variable *var;
+
+ /* Used below in the call to qsort. */
+ static int compare(const void *a, const void *b)
+ {
+ const temp_attr *const l = (const temp_attr *) a;
+ const temp_attr *const r = (const temp_attr *) b;
+
+ /* Reversed because we want a descending order sort below. */
+ return r->slots - l->slots;
+ }
+ } to_assign[16];
+
+ unsigned num_attr = 0;
+
+ foreach_list(node, &sh->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != ir_var_in))
+ continue;
+
+ /* The location was explicitly assigned, nothing to do here.
+ */
+ if (var->location != -1)
+ continue;
+
+ to_assign[num_attr].slots = count_attribute_slots(var->type);
+ to_assign[num_attr].var = var;
+ num_attr++;
+ }
+
+ /* If all of the attributes were assigned locations by the application (or
+ * are built-in attributes with fixed locations), return early. This should
+ * be the common case.
+ */
+ if (num_attr == 0)
+ return true;
+
+ qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare);
+
+ for (unsigned i = 0; i < num_attr; i++) {
+ /* Mask representing the contiguous slots that will be used by this
+ * attribute.
+ */
+ const unsigned use_mask = (1 << to_assign[i].slots) - 1;
+
+ int location = find_available_slots(used_locations, to_assign[i].slots);
+
+ if (location < 0) {
+ linker_error_printf(prog,
+ "insufficient contiguous attribute locations "
+ "available for vertex shader input `%s'",
+ to_assign[i].var->name);
+ return false;
+ }
+
+ to_assign[i].var->location = VERT_ATTRIB_GENERIC0 + location;
+ used_locations |= (use_mask << location);
+ }
+
+ return true;
+}
+
+
+void
+assign_varying_locations(glsl_shader *producer, glsl_shader *consumer)
+{
+ /* FINISHME: Set dynamically when geometry shader support is added. */
+ unsigned output_index = VERT_RESULT_VAR0;
+ unsigned input_index = FRAG_ATTRIB_VAR0;
+
+ /* Operate in a total of three passes.
+ *
+ * 1. Assign locations for any matching inputs and outputs.
+ *
+ * 2. Mark output variables in the producer that do not have locations as
+ * not being outputs. This lets the optimizer eliminate them.
+ *
+ * 3. Mark input variables in the consumer that do not have locations as
+ * not being inputs. This lets the optimizer eliminate them.
+ */
+
+ invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_VAR0);
+ invalidate_variable_locations(consumer, ir_var_in, FRAG_ATTRIB_VAR0);
+
+ foreach_list(node, &producer->ir) {
+ ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
+
+ if ((output_var == NULL) || (output_var->mode != ir_var_out)
+ || (output_var->location != -1))
+ continue;
+
+ ir_variable *const input_var =
+ consumer->symbols->get_variable(output_var->name);
+
+ if ((input_var == NULL) || (input_var->mode != ir_var_in))
+ continue;
+
+ assert(input_var->location == -1);
+
+ /* FINISHME: Location assignment will need some changes when arrays,
+ * FINISHME: matrices, and structures are allowed as shader inputs /
+ * FINISHME: outputs.
+ */
+ output_var->location = output_index;
+ input_var->location = input_index;
+
+ output_index++;
+ input_index++;
+ }
+
+ foreach_list(node, &producer->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != ir_var_out))
+ continue;
+
+ /* An 'out' variable is only really a shader output if its value is read
+ * by the following stage.
+ */
+ var->shader_out = (var->location != -1);
+ }
+
+ foreach_list(node, &consumer->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != ir_var_in))
+ continue;
+
+ /* An 'in' variable is only really a shader input if its value is written
+ * by the previous stage.
+ */
+ var->shader_in = (var->location != -1);
+ }
+}
+
+
+void
+link_shaders(struct glsl_program *prog)
+{
+ prog->LinkStatus = false;
+ prog->Validated = false;
+ prog->_Used = false;
+
+ if (prog->InfoLog != NULL)
+ talloc_free(prog->InfoLog);
+
+ prog->InfoLog = talloc_strdup(NULL, "");
+
+ /* Separate the shaders into groups based on their type.
+ */
+ struct glsl_shader **vert_shader_list;
+ unsigned num_vert_shaders = 0;
+ struct glsl_shader **frag_shader_list;
+ unsigned num_frag_shaders = 0;
+
+ vert_shader_list = (struct glsl_shader **)
+ calloc(2 * prog->NumShaders, sizeof(struct glsl_shader *));
+ frag_shader_list = &vert_shader_list[prog->NumShaders];
+
+ for (unsigned i = 0; i < prog->NumShaders; i++) {
+ switch (prog->Shaders[i]->Type) {
+ case GL_VERTEX_SHADER:
+ vert_shader_list[num_vert_shaders] = prog->Shaders[i];
+ num_vert_shaders++;
+ break;
+ case GL_FRAGMENT_SHADER:
+ frag_shader_list[num_frag_shaders] = prog->Shaders[i];
+ num_frag_shaders++;
+ break;
+ case GL_GEOMETRY_SHADER:
+ /* FINISHME: Support geometry shaders. */
+ assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER);
+ break;
+ }
+ }
+
+ /* FINISHME: Implement intra-stage linking. */
+ assert(num_vert_shaders <= 1);
+ assert(num_frag_shaders <= 1);
+
+ /* Verify that each of the per-target executables is valid.
+ */
+ if (!validate_vertex_shader_executable(prog, vert_shader_list[0])
+ || !validate_fragment_shader_executable(prog, frag_shader_list[0]))
+ goto done;
+
+
+ prog->_LinkedShaders = (struct glsl_shader **)
+ calloc(2, sizeof(struct glsl_shader *));
+ prog->_NumLinkedShaders = 0;
+
+ if (num_vert_shaders > 0) {
+ prog->_LinkedShaders[prog->_NumLinkedShaders] = vert_shader_list[0];
+ prog->_NumLinkedShaders++;
+ }
+
+ if (num_frag_shaders > 0) {
+ prog->_LinkedShaders[prog->_NumLinkedShaders] = frag_shader_list[0];
+ prog->_NumLinkedShaders++;
+ }
+
+ /* Here begins the inter-stage linking phase. Some initial validation is
+ * performed, then locations are assigned for uniforms, attributes, and
+ * varyings.
+ */
+ if (cross_validate_uniforms(prog)) {
+ /* Validate the inputs of each stage with the output of the preceeding
+ * stage.
+ */
+ for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) {
+ if (!cross_validate_outputs_to_inputs(prog,
+ prog->_LinkedShaders[i - 1],
+ prog->_LinkedShaders[i]))
+ goto done;
+ }
+
+ prog->LinkStatus = true;
+ }
+
+ /* FINISHME: Perform whole-program optimization here. */
+
+ assign_uniform_locations(prog);
+
+ if (prog->_LinkedShaders[0]->Type == GL_VERTEX_SHADER)
+ /* FINISHME: The value of the max_attribute_index parameter is
+ * FINISHME: implementation dependent based on the value of
+ * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
+ * FINISHME: at least 16, so hardcode 16 for now.
+ */
+ if (!assign_attribute_locations(prog, 16))
+ goto done;
+
+ for (unsigned i = 1; i < prog->_NumLinkedShaders; i++)
+ assign_varying_locations(prog->_LinkedShaders[i - 1],
+ prog->_LinkedShaders[i]);
+
+ /* FINISHME: Assign fragment shader output locations. */
+
+done:
+ free(vert_shader_list);
+}
--- /dev/null
+/*
+ * Copyright © 2008, 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.
+ */
+
+/**
+ * \file list.h
+ * \brief Doubly-linked list abstract container type.
+ *
+ * Each doubly-linked list has a sentinal head and tail node. These nodes
+ * contain no data. The head sentinal can be identified by its \c prev
+ * pointer being \c NULL. The tail sentinal can be identified by its
+ * \c next pointer being \c NULL.
+ *
+ * A list is empty if either the head sentinal's \c next pointer points to the
+ * tail sentinal or the tail sentinal's \c prev poiner points to the head
+ * sentinal.
+ *
+ * Instead of tracking two separate \c node structures and a \c list structure
+ * that points to them, the sentinal nodes are in a single structure. Noting
+ * that each sentinal node always has one \c NULL pointer, the \c NULL
+ * pointers occupy the same memory location. In the \c list structure
+ * contains a the following:
+ *
+ * - A \c head pointer that represents the \c next pointer of the
+ * head sentinal node.
+ * - A \c tail pointer that represents the \c prev pointer of the head
+ * sentinal node and the \c next pointer of the tail sentinal node. This
+ * pointer is \b always \c NULL.
+ * - A \c tail_prev pointer that represents the \c prev pointer of the
+ * tail sentinal node.
+ *
+ * Therefore, if \c head->next is \c NULL or \c tail_prev->prev is \c NULL,
+ * the list is empty.
+ *
+ * To anyone familiar with "exec lists" on the Amiga, this structure should
+ * be immediately recognizable. See the following link for the original Amiga
+ * operating system documentation on the subject.
+ *
+ * http://www.natami.net/dev/Libraries_Manual_guide/node02D7.html
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#pragma once
+#ifndef LIST_CONTAINER_H
+#define LIST_CONTAINER_H
+
+#ifndef __cplusplus
+#include <stddef.h>
+#include <talloc.h>
+#else
+extern "C" {
+#include <talloc.h>
+}
+#endif
+
+#include <assert.h>
+
+struct exec_node {
+ struct exec_node *next;
+ struct exec_node *prev;
+
+#ifdef __cplusplus
+ /* 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_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 *node)
+ {
+ talloc_free(node);
+ }
+
+ exec_node() : next(NULL), prev(NULL)
+ {
+ /* empty */
+ }
+
+ const exec_node *get_next() const
+ {
+ return next;
+ }
+
+ exec_node *get_next()
+ {
+ return next;
+ }
+
+ const exec_node *get_prev() const
+ {
+ return prev;
+ }
+
+ exec_node *get_prev()
+ {
+ return prev;
+ }
+
+ void remove()
+ {
+ next->prev = prev;
+ prev->next = next;
+ next = NULL;
+ prev = NULL;
+ }
+
+ /**
+ * Link a node with itself
+ *
+ * This creates a sort of degenerate list that is occasionally useful.
+ */
+ void self_link()
+ {
+ next = this;
+ prev = this;
+ }
+
+ /**
+ * Insert a node in the list after the current node
+ */
+ void insert_after(exec_node *after)
+ {
+ after->next = this->next;
+ after->prev = this;
+
+ this->next->prev = after;
+ this->next = after;
+ }
+ /**
+ * Insert a node in the list before the current node
+ */
+ void insert_before(exec_node *before)
+ {
+ before->next = this;
+ before->prev = this->prev;
+
+ this->prev->next = before;
+ this->prev = before;
+ }
+
+ /**
+ * Is this the sentinal at the tail of the list?
+ */
+ bool is_tail_sentinal() const
+ {
+ return this->next == NULL;
+ }
+
+ /**
+ * Is this the sentinal at the head of the list?
+ */
+ bool is_head_sentinal() const
+ {
+ return this->prev == NULL;
+ }
+#endif
+};
+
+
+#ifdef __cplusplus
+/* This macro will not work correctly if `t' uses virtual inheritance. If you
+ * are using virtual inheritance, you deserve a slow and painful death. Enjoy!
+ */
+#define exec_list_offsetof(t, f, p) \
+ (((char *) &((t *) p)->f) - ((char *) p))
+#else
+#define exec_list_offsetof(t, f, p) offsetof(t, f)
+#endif
+
+/**
+ * Get a pointer to the structure containing an exec_node
+ *
+ * Given a pointer to an \c exec_node embedded in a structure, get a pointer to
+ * the containing structure.
+ *
+ * \param type Base type of the structure containing the node
+ * \param node Pointer to the \c exec_node
+ * \param field Name of the field in \c type that is the embedded \c exec_node
+ */
+#define exec_node_data(type, node, field) \
+ ((type *) (((char *) node) - exec_list_offsetof(type, field, node)))
+
+#ifdef __cplusplus
+struct exec_node;
+
+class iterator {
+public:
+ void next()
+ {
+ }
+
+ void *get()
+ {
+ return NULL;
+ }
+
+ bool has_next() const
+ {
+ return false;
+ }
+};
+
+class exec_list_iterator : public iterator {
+public:
+ exec_list_iterator(exec_node *n) : node(n), _next(n->next)
+ {
+ /* empty */
+ }
+
+ void next()
+ {
+ node = _next;
+ _next = node->next;
+ }
+
+ void remove()
+ {
+ node->remove();
+ }
+
+ exec_node *get()
+ {
+ return node;
+ }
+
+ bool has_next() const
+ {
+ return _next != NULL;
+ }
+
+private:
+ exec_node *node;
+ exec_node *_next;
+};
+
+#define foreach_iter(iter_type, iter, container) \
+ for (iter_type iter = (container) . iterator(); iter.has_next(); iter.next())
+#endif
+
+
+struct exec_list {
+ struct exec_node *head;
+ struct exec_node *tail;
+ struct exec_node *tail_pred;
+
+#ifdef __cplusplus
+ exec_list()
+ {
+ make_empty();
+ }
+
+ void make_empty()
+ {
+ head = (exec_node *) & tail;
+ tail = NULL;
+ tail_pred = (exec_node *) & head;
+ }
+
+ bool is_empty() const
+ {
+ /* There are three ways to test whether a list is empty or not.
+ *
+ * - Check to see if the \c head points to the \c tail.
+ * - Check to see if the \c tail_pred points to the \c head.
+ * - Check to see if the \c head is the sentinal node by test whether its
+ * \c next pointer is \c NULL.
+ *
+ * The first two methods tend to generate better code on modern systems
+ * because they save a pointer dereference.
+ */
+ return head == (exec_node *) &tail;
+ }
+
+ const exec_node *get_head() const
+ {
+ return !is_empty() ? head : NULL;
+ }
+
+ exec_node *get_head()
+ {
+ return !is_empty() ? head : NULL;
+ }
+
+ const exec_node *get_tail() const
+ {
+ return !is_empty() ? tail_pred : NULL;
+ }
+
+ exec_node *get_tail()
+ {
+ return !is_empty() ? tail_pred : NULL;
+ }
+
+ void push_head(exec_node *n)
+ {
+ n->next = head;
+ n->prev = (exec_node *) &head;
+
+ n->next->prev = n;
+ head = n;
+ }
+
+ void push_tail(exec_node *n)
+ {
+ n->next = (exec_node *) &tail;
+ n->prev = tail_pred;
+
+ n->prev->next = n;
+ tail_pred = n;
+ }
+
+ void push_degenerate_list_at_head(exec_node *n)
+ {
+ assert(n->prev->next == n);
+
+ n->prev->next = head;
+ head->prev = n->prev;
+ n->prev = (exec_node *) &head;
+ head = n;
+ }
+
+ /**
+ * Move all of the nodes from this list to the target list
+ */
+ void move_nodes_to(exec_list *target)
+ {
+ if (is_empty()) {
+ target->make_empty();
+ } else {
+ target->head = head;
+ target->tail = NULL;
+ target->tail_pred = tail_pred;
+
+ target->head->prev = (exec_node *) &target->head;
+ target->tail_pred->next = (exec_node *) &target->tail;
+
+ make_empty();
+ }
+ }
+
+ exec_list_iterator iterator()
+ {
+ return exec_list_iterator(head);
+ }
+
+ exec_list_iterator iterator() const
+ {
+ return exec_list_iterator((exec_node *) head);
+ }
+#endif
+};
+
+#define foreach_list(__node, __list) \
+ for (exec_node * __node = (__list)->head \
+ ; (__node)->next != NULL \
+ ; (__node) = (__node)->next)
+
+#define foreach_list_const(__node, __list) \
+ for (const exec_node * __node = (__list)->head \
+ ; (__node)->next != NULL \
+ ; (__node) = (__node)->next)
+
+#define foreach_list_typed(__type, __node, __field, __list) \
+ for (__type * __node = \
+ exec_node_data(__type, (__list)->head, __field); \
+ (__node)->__field.next != NULL; \
+ (__node) = exec_node_data(__type, (__node)->__field.next, __field))
+
+#define foreach_list_typed_const(__type, __node, __field, __list) \
+ for (const __type * __node = \
+ exec_node_data(__type, (__list)->head, __field); \
+ (__node)->__field.next != NULL; \
+ (__node) = exec_node_data(__type, (__node)->__field.next, __field))
+
+#endif /* LIST_CONTAINER_H */
--- /dev/null
+/*
+ * 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 <cstdlib>
+#include <cstdio>
+#include <getopt.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "ast.h"
+#include "glsl_parser_extras.h"
+#include "glsl_parser.h"
+#include "ir_optimization.h"
+#include "ir_print_visitor.h"
+#include "program.h"
+
+/* Returned string will have 'ctx' as its talloc owner. */
+static char *
+load_text_file(void *ctx, const char *file_name, size_t *size)
+{
+ char *text = NULL;
+ struct stat st;
+ ssize_t total_read = 0;
+ int fd = open(file_name, O_RDONLY);
+
+ *size = 0;
+ if (fd < 0) {
+ return NULL;
+ }
+
+ if (fstat(fd, & st) == 0) {
+ text = (char *) talloc_size(ctx, st.st_size + 1);
+ if (text != NULL) {
+ do {
+ ssize_t bytes = read(fd, text + total_read,
+ st.st_size - total_read);
+ if (bytes < 0) {
+ free(text);
+ text = NULL;
+ break;
+ }
+
+ if (bytes == 0) {
+ break;
+ }
+
+ total_read += bytes;
+ } while (total_read < st.st_size);
+
+ text[total_read] = '\0';
+ *size = total_read;
+ }
+ }
+
+ close(fd);
+
+ return text;
+}
+
+
+void
+usage_fail(const char *name)
+{
+ printf("%s <filename.frag|filename.vert>\n", name);
+ exit(EXIT_FAILURE);
+}
+
+
+int dump_ast = 0;
+int dump_lir = 0;
+int do_link = 0;
+
+const struct option compiler_opts[] = {
+ { "dump-ast", 0, &dump_ast, 1 },
+ { "dump-lir", 0, &dump_lir, 1 },
+ { "link", 0, &do_link, 1 },
+ { NULL, 0, NULL, 0 }
+};
+
+void
+compile_shader(struct glsl_shader *shader)
+{
+ struct _mesa_glsl_parse_state *state;
+
+ state = talloc_zero(talloc_parent(shader), struct _mesa_glsl_parse_state);
+
+ switch (shader->Type) {
+ case GL_VERTEX_SHADER: state->target = vertex_shader; break;
+ case GL_FRAGMENT_SHADER: state->target = fragment_shader; break;
+ case GL_GEOMETRY_SHADER: state->target = geometry_shader; break;
+ }
+
+ state->scanner = NULL;
+ state->translation_unit.make_empty();
+ state->symbols = new(shader) glsl_symbol_table;
+ state->info_log = talloc_strdup(shader, "");
+ state->error = false;
+ state->temp_index = 0;
+ state->loop_or_switch_nesting = NULL;
+ state->ARB_texture_rectangle_enable = true;
+
+ /* Create a new context for the preprocessor output. Ultimately, this
+ * should probably be the parser context, but there isn't one yet.
+ */
+ const char *source = shader->Source;
+ state->error = preprocess(shader, &source, &state->info_log);
+
+ if (!state->error) {
+ _mesa_glsl_lexer_ctor(state, source);
+ _mesa_glsl_parse(state);
+ _mesa_glsl_lexer_dtor(state);
+ }
+
+ if (dump_ast) {
+ foreach_list_const(n, &state->translation_unit) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
+ }
+ printf("\n\n");
+ }
+
+ shader->ir.make_empty();
+ if (!state->error && !state->translation_unit.is_empty())
+ _mesa_ast_to_hir(&shader->ir, state);
+
+ validate_ir_tree(&shader->ir);
+
+ /* Optimization passes */
+ if (!state->error && !shader->ir.is_empty()) {
+ bool progress;
+ do {
+ progress = false;
+
+ progress = do_function_inlining(&shader->ir) || progress;
+ progress = do_if_simplification(&shader->ir) || progress;
+ progress = do_copy_propagation(&shader->ir) || progress;
+ progress = do_dead_code_local(&shader->ir) || progress;
+ progress = do_dead_code_unlinked(&shader->ir) || progress;
+ progress = do_constant_variable_unlinked(&shader->ir) || progress;
+ progress = do_constant_folding(&shader->ir) || progress;
+ progress = do_vec_index_to_swizzle(&shader->ir) || progress;
+ progress = do_swizzle_swizzle(&shader->ir) || progress;
+ } while (progress);
+ }
+
+ validate_ir_tree(&shader->ir);
+
+ /* Print out the resulting IR */
+ if (!state->error && dump_lir) {
+ _mesa_print_ir(&shader->ir, state);
+ }
+
+ shader->symbols = state->symbols;
+ shader->CompileStatus = !state->error;
+
+ if (shader->InfoLog)
+ talloc_free(shader->InfoLog);
+
+ shader->InfoLog = state->info_log;
+
+ talloc_free(state);
+
+ return;
+}
+
+int
+main(int argc, char **argv)
+{
+ int status = EXIT_SUCCESS;
+
+ int c;
+ int idx = 0;
+ while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1)
+ /* empty */ ;
+
+
+ if (argc <= optind)
+ usage_fail(argv[0]);
+
+ struct glsl_program *whole_program;
+
+ whole_program = talloc_zero (NULL, struct glsl_program);
+ assert(whole_program != NULL);
+
+ for (/* empty */; argc > optind; optind++) {
+ whole_program->Shaders = (struct glsl_shader **)
+ talloc_realloc(whole_program, whole_program->Shaders,
+ struct glsl_shader *, whole_program->NumShaders + 1);
+ assert(whole_program->Shaders != NULL);
+
+ struct glsl_shader *shader = talloc_zero(whole_program, glsl_shader);
+
+ whole_program->Shaders[whole_program->NumShaders] = shader;
+ whole_program->NumShaders++;
+
+ const unsigned len = strlen(argv[optind]);
+ if (len < 6)
+ usage_fail(argv[0]);
+
+ const char *const ext = & argv[optind][len - 5];
+ if (strncmp(".vert", ext, 5) == 0)
+ shader->Type = GL_VERTEX_SHADER;
+ else if (strncmp(".geom", ext, 5) == 0)
+ shader->Type = GL_GEOMETRY_SHADER;
+ else if (strncmp(".frag", ext, 5) == 0)
+ shader->Type = GL_FRAGMENT_SHADER;
+ else
+ usage_fail(argv[0]);
+
+ shader->Source = load_text_file(whole_program,
+ argv[optind], &shader->SourceLen);
+ if (shader->Source == NULL) {
+ printf("File \"%s\" does not exist.\n", argv[optind]);
+ exit(EXIT_FAILURE);
+ }
+
+ compile_shader(shader);
+
+ if (!shader->CompileStatus) {
+ printf("Info log for %s:\n%s\n", argv[optind], shader->InfoLog);
+ status = EXIT_FAILURE;
+ break;
+ }
+ }
+
+ if ((status == EXIT_SUCCESS) && do_link) {
+ link_shaders(whole_program);
+ status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ talloc_free(whole_program);
+
+ return status;
+}
--- /dev/null
+#include <assert.h>
+#include <stdlib.h>
+
+#define _mesa_malloc(x) malloc(x)
+#define _mesa_free(x) free(x)
+#define _mesa_calloc(x) calloc(1,x)
--- /dev/null
+/*
+ * 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
+
+#define MAX_DRAW_BUFFERS 8
+#define MAX_VARYING 16
+
+#include <GL/gl.h>
+
+/**
+ * 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 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_COLOR = 1,
+ FRAG_RESULT_DATA0 = 2,
+ FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
+} gl_frag_result;
+
+/**
+ * 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_UNDEFINED, /**< Invalid/TBD value */
+ PROGRAM_FILE_MAX
+} gl_register_file;
+
+/**
+ * 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;
+
+#endif /* MTYPES_H */
--- /dev/null
+/**
+ * \file simple_list.h
+ * Simple macros for type-safe, intrusive lists.
+ *
+ * Intended to work with a list sentinal which is created as an empty
+ * list. Insert & delete are O(1).
+ *
+ * \author
+ * (C) 1997, Keith Whitwell
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 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.
+ */
+
+
+#ifndef _SIMPLE_LIST_H
+#define _SIMPLE_LIST_H
+
+struct simple_node {
+ struct simple_node *next;
+ struct simple_node *prev;
+};
+
+/**
+ * Remove an element from list.
+ *
+ * \param elem element to remove.
+ */
+#define remove_from_list(elem) \
+do { \
+ (elem)->next->prev = (elem)->prev; \
+ (elem)->prev->next = (elem)->next; \
+} while (0)
+
+/**
+ * Insert an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_head(list, elem) \
+do { \
+ (elem)->prev = list; \
+ (elem)->next = (list)->next; \
+ (list)->next->prev = elem; \
+ (list)->next = elem; \
+} while(0)
+
+/**
+ * Insert an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_tail(list, elem) \
+do { \
+ (elem)->next = list; \
+ (elem)->prev = (list)->prev; \
+ (list)->prev->next = elem; \
+ (list)->prev = elem; \
+} while(0)
+
+/**
+ * Move an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_head(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_head(list, elem); \
+} while (0)
+
+/**
+ * Move an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_tail(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_tail(list, elem); \
+} while (0)
+
+/**
+ * Consatinate a cyclic list to a list
+ *
+ * Appends the sequence of nodes starting with \c tail to the list \c head.
+ * A "cyclic list" is a list that does not have a sentinal node. This means
+ * that the data pointed to by \c tail is an actual node, not a dataless
+ * sentinal. Note that if \c tail constist of a single node, this macro
+ * behaves identically to \c insert_at_tail
+ *
+ * \param head Head of the list to be appended to. This may or may not
+ * be a cyclic list.
+ * \param tail Head of the cyclic list to be appended to \c head.
+ * \param temp Temporary \c simple_list used by the macro
+ *
+ * \sa insert_at_tail
+ */
+#define concat_list_and_cycle(head, tail, temp) \
+do { \
+ (head)->prev->next = (tail); \
+ (tail)->prev->next = (head); \
+ (temp) = (head)->prev; \
+ (head)->prev = (tail)->prev; \
+ (tail)->prev = (temp); \
+} while (0)
+
+#define concat_list(head, next_list) \
+do { \
+ (next_list)->next->prev = (head)->prev; \
+ (next_list)->prev->next = (head); \
+ (head)->prev->next = (next_list)->next; \
+ (head)->prev = (next_list)->prev; \
+} while (0)
+
+/**
+ * Make a empty list empty.
+ *
+ * \param sentinal list (sentinal element).
+ */
+#define make_empty_list(sentinal) \
+do { \
+ (sentinal)->next = sentinal; \
+ (sentinal)->prev = sentinal; \
+} while (0)
+
+/**
+ * Get list first element.
+ *
+ * \param list list.
+ *
+ * \return pointer to first element.
+ */
+#define first_elem(list) ((list)->next)
+
+/**
+ * Get list last element.
+ *
+ * \param list list.
+ *
+ * \return pointer to last element.
+ */
+#define last_elem(list) ((list)->prev)
+
+/**
+ * Get next element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to next element.
+ */
+#define next_elem(elem) ((elem)->next)
+
+/**
+ * Get previous element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to previous element.
+ */
+#define prev_elem(elem) ((elem)->prev)
+
+/**
+ * Test whether element is at end of the list.
+ *
+ * \param list list.
+ * \param elem element.
+ *
+ * \return non-zero if element is at end of list, or zero otherwise.
+ */
+#define at_end(list, elem) ((elem) == (list))
+
+/**
+ * Test if a list is empty.
+ *
+ * \param list list.
+ *
+ * \return non-zero if list empty, or zero otherwise.
+ */
+#define is_empty_list(list) ((list)->next == (list))
+
+/**
+ * Walk through the elements of a list.
+ *
+ * \param ptr pointer to the current element.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach(ptr, list) \
+ for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next )
+
+/**
+ * Walk through the elements of a list.
+ *
+ * Same as #foreach but lets you unlink the current value during a list
+ * traversal. Useful for freeing a list, element by element.
+ *
+ * \param ptr pointer to the current element.
+ * \param t temporary pointer.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach_s(ptr, t, list) \
+ for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
+
+#endif
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.3
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-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.
+ */
+
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#if 0
+#include "main/glheader.h"
+#else
+#define _mesa_strdup strdup
+#define _mesa_snprintf snprintf
+#define ASSERT assert
+#endif
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "prog_instruction.h"
+
+
+/**
+ * Initialize program instruction fields to defaults.
+ * \param inst first instruction to initialize
+ * \param count number of instructions to initialize
+ */
+void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
+{
+ GLuint i;
+
+ memset(inst, 0, count * sizeof(struct prog_instruction));
+
+ for (i = 0; i < count; i++) {
+ inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
+ inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+
+ inst[i].DstReg.File = PROGRAM_UNDEFINED;
+ inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ inst[i].DstReg.CondMask = COND_TR;
+ inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
+
+ inst[i].SaturateMode = SATURATE_OFF;
+ inst[i].Precision = FLOAT32;
+ }
+}
+
+
+/**
+ * Allocate an array of program instructions.
+ * \param numInst number of instructions
+ * \return pointer to instruction memory
+ */
+struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst)
+{
+ return (struct prog_instruction *)
+ calloc(1, numInst * sizeof(struct prog_instruction));
+}
+
+
+/**
+ * Reallocate memory storing an array of program instructions.
+ * This is used when we need to append additional instructions onto an
+ * program.
+ * \param oldInst pointer to first of old/src instructions
+ * \param numOldInst number of instructions at <oldInst>
+ * \param numNewInst desired size of new instruction array.
+ * \return pointer to start of new instruction array.
+ */
+struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+ GLuint numOldInst, GLuint numNewInst)
+{
+ struct prog_instruction *newInst;
+
+ (void)numOldInst;
+ newInst = (struct prog_instruction *)
+ realloc(oldInst,
+ numNewInst * sizeof(struct prog_instruction));
+
+ return newInst;
+}
+
+
+/**
+ * Copy an array of program instructions.
+ * \param dest pointer to destination.
+ * \param src pointer to source.
+ * \param n number of instructions to copy.
+ * \return pointer to destination.
+ */
+struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+ const struct prog_instruction *src, GLuint n)
+{
+ GLuint i;
+ memcpy(dest, src, n * sizeof(struct prog_instruction));
+ for (i = 0; i < n; i++) {
+ if (src[i].Comment)
+ dest[i].Comment = _mesa_strdup(src[i].Comment);
+ }
+ return dest;
+}
+
+
+/**
+ * Free an array of instructions
+ */
+void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
+{
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (inst[i].Data)
+ free(inst[i].Data);
+ if (inst[i].Comment)
+ free((char *) inst[i].Comment);
+ }
+ free(inst);
+}
+
+
+/**
+ * Basic info about each instruction
+ */
+struct instruction_info
+{
+ gl_inst_opcode Opcode;
+ const char *Name;
+ GLuint NumSrcRegs;
+ GLuint NumDstRegs;
+};
+
+/**
+ * Instruction info
+ * \note Opcode should equal array index!
+ */
+static const struct instruction_info InstInfo[MAX_OPCODE] = {
+ { OPCODE_NOP, "NOP", 0, 0 },
+ { OPCODE_ABS, "ABS", 1, 1 },
+ { OPCODE_ADD, "ADD", 2, 1 },
+ { OPCODE_AND, "AND", 2, 1 },
+ { OPCODE_ARA, "ARA", 1, 1 },
+ { OPCODE_ARL, "ARL", 1, 1 },
+ { OPCODE_ARL_NV, "ARL_NV", 1, 1 },
+ { OPCODE_ARR, "ARL", 1, 1 },
+ { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
+ { OPCODE_BGNSUB, "BGNSUB", 0, 0 },
+ { OPCODE_BRA, "BRA", 0, 0 },
+ { OPCODE_BRK, "BRK", 0, 0 },
+ { OPCODE_CAL, "CAL", 0, 0 },
+ { OPCODE_CMP, "CMP", 3, 1 },
+ { OPCODE_CONT, "CONT", 0, 0 },
+ { OPCODE_COS, "COS", 1, 1 },
+ { OPCODE_DDX, "DDX", 1, 1 },
+ { OPCODE_DDY, "DDY", 1, 1 },
+ { OPCODE_DP2, "DP2", 2, 1 },
+ { OPCODE_DP2A, "DP2A", 3, 1 },
+ { OPCODE_DP3, "DP3", 2, 1 },
+ { OPCODE_DP4, "DP4", 2, 1 },
+ { OPCODE_DPH, "DPH", 2, 1 },
+ { OPCODE_DST, "DST", 2, 1 },
+ { OPCODE_ELSE, "ELSE", 0, 0 },
+ { OPCODE_END, "END", 0, 0 },
+ { OPCODE_ENDIF, "ENDIF", 0, 0 },
+ { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
+ { OPCODE_ENDSUB, "ENDSUB", 0, 0 },
+ { OPCODE_EX2, "EX2", 1, 1 },
+ { OPCODE_EXP, "EXP", 1, 1 },
+ { OPCODE_FLR, "FLR", 1, 1 },
+ { OPCODE_FRC, "FRC", 1, 1 },
+ { OPCODE_IF, "IF", 1, 0 },
+ { OPCODE_KIL, "KIL", 1, 0 },
+ { OPCODE_KIL_NV, "KIL_NV", 0, 0 },
+ { OPCODE_LG2, "LG2", 1, 1 },
+ { OPCODE_LIT, "LIT", 1, 1 },
+ { OPCODE_LOG, "LOG", 1, 1 },
+ { OPCODE_LRP, "LRP", 3, 1 },
+ { OPCODE_MAD, "MAD", 3, 1 },
+ { OPCODE_MAX, "MAX", 2, 1 },
+ { OPCODE_MIN, "MIN", 2, 1 },
+ { OPCODE_MOV, "MOV", 1, 1 },
+ { OPCODE_MUL, "MUL", 2, 1 },
+ { OPCODE_NOISE1, "NOISE1", 1, 1 },
+ { OPCODE_NOISE2, "NOISE2", 1, 1 },
+ { OPCODE_NOISE3, "NOISE3", 1, 1 },
+ { OPCODE_NOISE4, "NOISE4", 1, 1 },
+ { OPCODE_NOT, "NOT", 1, 1 },
+ { OPCODE_NRM3, "NRM3", 1, 1 },
+ { OPCODE_NRM4, "NRM4", 1, 1 },
+ { OPCODE_OR, "OR", 2, 1 },
+ { OPCODE_PK2H, "PK2H", 1, 1 },
+ { OPCODE_PK2US, "PK2US", 1, 1 },
+ { OPCODE_PK4B, "PK4B", 1, 1 },
+ { OPCODE_PK4UB, "PK4UB", 1, 1 },
+ { OPCODE_POW, "POW", 2, 1 },
+ { OPCODE_POPA, "POPA", 0, 0 },
+ { OPCODE_PRINT, "PRINT", 1, 0 },
+ { OPCODE_PUSHA, "PUSHA", 0, 0 },
+ { OPCODE_RCC, "RCC", 1, 1 },
+ { OPCODE_RCP, "RCP", 1, 1 },
+ { OPCODE_RET, "RET", 0, 0 },
+ { OPCODE_RFL, "RFL", 1, 1 },
+ { OPCODE_RSQ, "RSQ", 1, 1 },
+ { OPCODE_SCS, "SCS", 1, 1 },
+ { OPCODE_SEQ, "SEQ", 2, 1 },
+ { OPCODE_SFL, "SFL", 0, 1 },
+ { OPCODE_SGE, "SGE", 2, 1 },
+ { OPCODE_SGT, "SGT", 2, 1 },
+ { OPCODE_SIN, "SIN", 1, 1 },
+ { OPCODE_SLE, "SLE", 2, 1 },
+ { OPCODE_SLT, "SLT", 2, 1 },
+ { OPCODE_SNE, "SNE", 2, 1 },
+ { OPCODE_SSG, "SSG", 1, 1 },
+ { OPCODE_STR, "STR", 0, 1 },
+ { OPCODE_SUB, "SUB", 2, 1 },
+ { OPCODE_SWZ, "SWZ", 1, 1 },
+ { OPCODE_TEX, "TEX", 1, 1 },
+ { OPCODE_TXB, "TXB", 1, 1 },
+ { OPCODE_TXD, "TXD", 3, 1 },
+ { OPCODE_TXL, "TXL", 1, 1 },
+ { OPCODE_TXP, "TXP", 1, 1 },
+ { OPCODE_TXP_NV, "TXP_NV", 1, 1 },
+ { OPCODE_TRUNC, "TRUNC", 1, 1 },
+ { OPCODE_UP2H, "UP2H", 1, 1 },
+ { OPCODE_UP2US, "UP2US", 1, 1 },
+ { OPCODE_UP4B, "UP4B", 1, 1 },
+ { OPCODE_UP4UB, "UP4UB", 1, 1 },
+ { OPCODE_X2D, "X2D", 3, 1 },
+ { OPCODE_XOR, "XOR", 2, 1 },
+ { OPCODE_XPD, "XPD", 2, 1 }
+};
+
+
+/**
+ * Return the number of src registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode)
+{
+ ASSERT(opcode < MAX_OPCODE);
+ ASSERT(opcode == InstInfo[opcode].Opcode);
+ ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+ return InstInfo[opcode].NumSrcRegs;
+}
+
+
+/**
+ * Return the number of dst registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
+{
+ ASSERT(opcode < MAX_OPCODE);
+ ASSERT(opcode == InstInfo[opcode].Opcode);
+ ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+ return InstInfo[opcode].NumDstRegs;
+}
+
+
+GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode)
+{
+ return (opcode == OPCODE_TEX ||
+ opcode == OPCODE_TXB ||
+ opcode == OPCODE_TXD ||
+ opcode == OPCODE_TXL ||
+ opcode == OPCODE_TXP);
+}
+
+
+/**
+ * Check if there's a potential src/dst register data dependency when
+ * using SOA execution.
+ * Example:
+ * MOV T, T.yxwz;
+ * This would expand into:
+ * MOV t0, t1;
+ * MOV t1, t0;
+ * MOV t2, t3;
+ * MOV t3, t2;
+ * The second instruction will have the wrong value for t0 if executed as-is.
+ */
+GLboolean
+_mesa_check_soa_dependencies(const struct prog_instruction *inst)
+{
+ GLuint i, chan;
+
+ if (inst->DstReg.WriteMask == WRITEMASK_X ||
+ inst->DstReg.WriteMask == WRITEMASK_Y ||
+ inst->DstReg.WriteMask == WRITEMASK_Z ||
+ inst->DstReg.WriteMask == WRITEMASK_W ||
+ inst->DstReg.WriteMask == 0x0) {
+ /* no chance of data dependency */
+ return GL_FALSE;
+ }
+
+ /* loop over src regs */
+ for (i = 0; i < 3; i++) {
+ if (inst->SrcReg[i].File == inst->DstReg.File &&
+ inst->SrcReg[i].Index == inst->DstReg.Index) {
+ /* loop over dest channels */
+ GLuint channelsWritten = 0x0;
+ for (chan = 0; chan < 4; chan++) {
+ if (inst->DstReg.WriteMask & (1 << chan)) {
+ /* check if we're reading a channel that's been written */
+ GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
+ if (swizzle <= SWIZZLE_W &&
+ (channelsWritten & (1 << swizzle))) {
+ return GL_TRUE;
+ }
+
+ channelsWritten |= (1 << chan);
+ }
+ }
+ }
+ }
+ return GL_FALSE;
+}
+
+
+/**
+ * Return string name for given program opcode.
+ */
+const char *
+_mesa_opcode_string(gl_inst_opcode opcode)
+{
+ if (opcode < MAX_OPCODE)
+ return InstInfo[opcode].Name;
+ else {
+ static char s[20];
+ _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
+ return s;
+ }
+}
+
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.3
+ *
+ * Copyright (C) 1999-2008 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.
+ */
+
+
+/**
+ * \file prog_instruction.h
+ *
+ * Vertex/fragment program instruction datatypes and constants.
+ *
+ * \author Brian Paul
+ * \author Keith Whitwell
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+
+#ifndef PROG_INSTRUCTION_H
+#define PROG_INSTRUCTION_H
+
+
+#include "main/mtypes.h"
+
+
+/**
+ * Swizzle indexes.
+ * Do not change!
+ */
+/*@{*/
+#define SWIZZLE_X 0
+#define SWIZZLE_Y 1
+#define SWIZZLE_Z 2
+#define SWIZZLE_W 3
+#define SWIZZLE_ZERO 4 /**< For SWZ instruction only */
+#define SWIZZLE_ONE 5 /**< For SWZ instruction only */
+#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */
+/*@}*/
+
+#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
+#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3)
+#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
+#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
+
+#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
+#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
+#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
+#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
+#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/**
+ * Writemask values, 1 bit per component.
+ */
+/*@{*/
+#define WRITEMASK_X 0x1
+#define WRITEMASK_Y 0x2
+#define WRITEMASK_XY 0x3
+#define WRITEMASK_Z 0x4
+#define WRITEMASK_XZ 0x5
+#define WRITEMASK_YZ 0x6
+#define WRITEMASK_XYZ 0x7
+#define WRITEMASK_W 0x8
+#define WRITEMASK_XW 0x9
+#define WRITEMASK_YW 0xa
+#define WRITEMASK_XYW 0xb
+#define WRITEMASK_ZW 0xc
+#define WRITEMASK_XZW 0xd
+#define WRITEMASK_YZW 0xe
+#define WRITEMASK_XYZW 0xf
+/*@}*/
+
+
+/**
+ * Condition codes
+ */
+/*@{*/
+#define COND_GT 1 /**< greater than zero */
+#define COND_EQ 2 /**< equal to zero */
+#define COND_LT 3 /**< less than zero */
+#define COND_UN 4 /**< unordered (NaN) */
+#define COND_GE 5 /**< greater than or equal to zero */
+#define COND_LE 6 /**< less than or equal to zero */
+#define COND_NE 7 /**< not equal to zero */
+#define COND_TR 8 /**< always true */
+#define COND_FL 9 /**< always false */
+/*@}*/
+
+
+/**
+ * Instruction precision for GL_NV_fragment_program
+ */
+/*@{*/
+#define FLOAT32 0x1
+#define FLOAT16 0x2
+#define FIXED12 0x4
+/*@}*/
+
+
+/**
+ * Saturation modes when storing values.
+ */
+/*@{*/
+#define SATURATE_OFF 0
+#define SATURATE_ZERO_ONE 1
+/*@}*/
+
+
+/**
+ * Per-component negation masks
+ */
+/*@{*/
+#define NEGATE_X 0x1
+#define NEGATE_Y 0x2
+#define NEGATE_Z 0x4
+#define NEGATE_W 0x8
+#define NEGATE_XYZ 0x7
+#define NEGATE_XYZW 0xf
+#define NEGATE_NONE 0x0
+/*@}*/
+
+
+/**
+ * Program instruction opcodes, for both vertex and fragment programs.
+ * \note changes to this opcode list must be reflected in t_vb_arbprogram.c
+ */
+typedef enum prog_opcode {
+ /* ARB_vp ARB_fp NV_vp NV_fp GLSL */
+ /*------------------------------------------*/
+ OPCODE_NOP = 0, /* X */
+ OPCODE_ABS, /* X X 1.1 X */
+ OPCODE_ADD, /* X X X X X */
+ OPCODE_AND, /* */
+ OPCODE_ARA, /* 2 */
+ OPCODE_ARL, /* X X */
+ OPCODE_ARL_NV, /* 2 */
+ OPCODE_ARR, /* 2 */
+ OPCODE_BGNLOOP, /* opt */
+ OPCODE_BGNSUB, /* opt */
+ OPCODE_BRA, /* 2 X */
+ OPCODE_BRK, /* 2 opt */
+ OPCODE_CAL, /* 2 2 */
+ OPCODE_CMP, /* X */
+ OPCODE_CONT, /* opt */
+ OPCODE_COS, /* X 2 X X */
+ OPCODE_DDX, /* X X */
+ OPCODE_DDY, /* X X */
+ OPCODE_DP2, /* 2 */
+ OPCODE_DP2A, /* 2 */
+ OPCODE_DP3, /* X X X X X */
+ OPCODE_DP4, /* X X X X X */
+ OPCODE_DPH, /* X X 1.1 */
+ OPCODE_DST, /* X X X X */
+ OPCODE_ELSE, /* X */
+ OPCODE_END, /* X X X X opt */
+ OPCODE_ENDIF, /* opt */
+ OPCODE_ENDLOOP, /* opt */
+ OPCODE_ENDSUB, /* opt */
+ OPCODE_EX2, /* X X 2 X X */
+ OPCODE_EXP, /* X X X */
+ OPCODE_FLR, /* X X 2 X X */
+ OPCODE_FRC, /* X X 2 X X */
+ OPCODE_IF, /* opt */
+ OPCODE_KIL, /* X */
+ OPCODE_KIL_NV, /* X X */
+ OPCODE_LG2, /* X X 2 X X */
+ OPCODE_LIT, /* X X X X */
+ OPCODE_LOG, /* X X X */
+ OPCODE_LRP, /* X X */
+ OPCODE_MAD, /* X X X X X */
+ OPCODE_MAX, /* X X X X X */
+ OPCODE_MIN, /* X X X X X */
+ OPCODE_MOV, /* X X X X X */
+ OPCODE_MUL, /* X X X X X */
+ OPCODE_NOISE1, /* X */
+ OPCODE_NOISE2, /* X */
+ OPCODE_NOISE3, /* X */
+ OPCODE_NOISE4, /* X */
+ OPCODE_NOT, /* */
+ OPCODE_NRM3, /* */
+ OPCODE_NRM4, /* */
+ OPCODE_OR, /* */
+ OPCODE_PK2H, /* X */
+ OPCODE_PK2US, /* X */
+ OPCODE_PK4B, /* X */
+ OPCODE_PK4UB, /* X */
+ OPCODE_POW, /* X X X X */
+ OPCODE_POPA, /* 3 */
+ OPCODE_PRINT, /* X X */
+ OPCODE_PUSHA, /* 3 */
+ OPCODE_RCC, /* 1.1 */
+ OPCODE_RCP, /* X X X X X */
+ OPCODE_RET, /* 2 2 */
+ OPCODE_RFL, /* X X */
+ OPCODE_RSQ, /* X X X X X */
+ OPCODE_SCS, /* X */
+ OPCODE_SEQ, /* 2 X X */
+ OPCODE_SFL, /* 2 X */
+ OPCODE_SGE, /* X X X X X */
+ OPCODE_SGT, /* 2 X X */
+ OPCODE_SIN, /* X 2 X X */
+ OPCODE_SLE, /* 2 X X */
+ OPCODE_SLT, /* X X X X X */
+ OPCODE_SNE, /* 2 X X */
+ OPCODE_SSG, /* 2 */
+ OPCODE_STR, /* 2 X */
+ OPCODE_SUB, /* X X 1.1 X X */
+ OPCODE_SWZ, /* X X */
+ OPCODE_TEX, /* X 3 X X */
+ OPCODE_TXB, /* X 3 X */
+ OPCODE_TXD, /* X X */
+ OPCODE_TXL, /* 3 2 X */
+ OPCODE_TXP, /* X X */
+ OPCODE_TXP_NV, /* 3 X */
+ OPCODE_TRUNC, /* X */
+ OPCODE_UP2H, /* X */
+ OPCODE_UP2US, /* X */
+ OPCODE_UP4B, /* X */
+ OPCODE_UP4UB, /* X */
+ OPCODE_X2D, /* X */
+ OPCODE_XOR, /* */
+ OPCODE_XPD, /* X X X */
+ MAX_OPCODE
+} gl_inst_opcode;
+
+
+/**
+ * Number of bits for the src/dst register Index field.
+ * This limits the size of temp/uniform register files.
+ */
+#define INST_INDEX_BITS 10
+
+
+/**
+ * Instruction source register.
+ */
+struct prog_src_register
+{
+ GLuint File:4; /**< One of the PROGRAM_* register file values. */
+ GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
+ * May be negative for relative addressing.
+ */
+ GLuint Swizzle:12;
+ GLuint RelAddr:1;
+
+ /** Take the component-wise absolute value */
+ GLuint Abs:1;
+
+ /**
+ * Post-Abs negation.
+ * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ
+ * instruction which allows per-component negation.
+ */
+ GLuint Negate:4;
+};
+
+
+/**
+ * Instruction destination register.
+ */
+struct prog_dst_register
+{
+ GLuint File:4; /**< One of the PROGRAM_* register file values */
+ GLuint Index:INST_INDEX_BITS; /**< Unsigned, never negative */
+ GLuint WriteMask:4;
+ GLuint RelAddr:1;
+
+ /**
+ * \name Conditional destination update control.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ /*@{*/
+ /**
+ * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
+ * NE, TR, or UN). Dest reg is only written to if the matching
+ * (swizzled) condition code value passes. When a conditional update mask
+ * is not specified, this will be \c COND_TR.
+ */
+ GLuint CondMask:4;
+
+ /**
+ * Condition code swizzle value.
+ */
+ GLuint CondSwizzle:12;
+
+ /**
+ * Selects the condition code register to use for conditional destination
+ * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only
+ * condition code register 0 is available. In NV_vertex_program3 mode,
+ * condition code registers 0 and 1 are available.
+ */
+ GLuint CondSrc:1;
+ /*@}*/
+};
+
+
+/**
+ * Vertex/fragment program instruction.
+ */
+struct prog_instruction
+{
+ gl_inst_opcode Opcode;
+ struct prog_src_register SrcReg[3];
+ struct prog_dst_register DstReg;
+
+ /**
+ * Indicates that the instruction should update the condition code
+ * register.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ GLuint CondUpdate:1;
+
+ /**
+ * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
+ * condition code register that is to be updated.
+ *
+ * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
+ * code register 0 is available. In GL_NV_vertex_program3 mode, condition
+ * code registers 0 and 1 are available.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ GLuint CondDst:1;
+
+ /**
+ * Saturate each value of the vectored result to the range [0,1] or the
+ * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is
+ * only available in NV_fragment_program2 mode.
+ * Value is one of the SATURATE_* tokens.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
+ */
+ GLuint SaturateMode:2;
+
+ /**
+ * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option.
+ */
+ GLuint Precision:3;
+
+ /**
+ * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
+ */
+ /*@{*/
+ /** Source texture unit. */
+ GLuint TexSrcUnit:5;
+
+ /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
+ GLuint TexSrcTarget:3;
+
+ /** True if tex instruction should do shadow comparison */
+ GLuint TexShadow:1;
+ /*@}*/
+
+ /**
+ * For BRA and CAL instructions, the location to jump to.
+ * For BGNLOOP, points to ENDLOOP (and vice-versa).
+ * For BRK, points to BGNLOOP (which points to ENDLOOP).
+ * For IF, points to ELSE or ENDIF.
+ * For ELSE, points to ENDIF.
+ */
+ GLint BranchTarget;
+
+ /** for debugging purposes */
+ const char *Comment;
+
+ /** Arbitrary data. Used for OPCODE_PRINT and some drivers */
+ void *Data;
+
+ /** for driver use (try to remove someday) */
+ GLint Aux;
+};
+
+
+extern void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
+
+extern struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst);
+
+extern struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+ GLuint numOldInst, GLuint numNewInst);
+
+extern struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+ const struct prog_instruction *src, GLuint n);
+
+extern void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
+
+extern GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode);
+
+extern GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_check_soa_dependencies(const struct prog_instruction *inst);
+
+extern const char *
+_mesa_opcode_string(gl_inst_opcode opcode);
+
+
+#endif /* PROG_INSTRUCTION_H */
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.3
+ *
+ * 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 prog_print.c
+ * Print vertex/fragment programs - for debugging.
+ * \author Brian Paul
+ */
+
+#if 0
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#else
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+struct gl_program {
+ int Target;
+};
+
+void _mesa_problem(void *ctx, char *msg)
+{
+ (void)ctx;
+ fprintf(stderr, "%s", msg);
+ exit(1);
+}
+
+#endif
+
+#include "prog_instruction.h"
+#include "prog_print.h"
+
+
+
+/**
+ * Return string name for given program/register file.
+ */
+static const char *
+file_string(gl_register_file f, gl_prog_print_mode mode)
+{
+ (void)mode;
+ switch (f) {
+ case PROGRAM_TEMPORARY:
+ return "TEMP";
+ case PROGRAM_LOCAL_PARAM:
+ return "LOCAL";
+ case PROGRAM_ENV_PARAM:
+ return "ENV";
+ case PROGRAM_STATE_VAR:
+ return "STATE";
+ case PROGRAM_INPUT:
+ return "INPUT";
+ case PROGRAM_OUTPUT:
+ return "OUTPUT";
+ case PROGRAM_NAMED_PARAM:
+ return "NAMED";
+ case PROGRAM_CONSTANT:
+ return "CONST";
+ case PROGRAM_UNIFORM:
+ return "UNIFORM";
+ case PROGRAM_VARYING:
+ return "VARYING";
+ case PROGRAM_WRITE_ONLY:
+ return "WRITE_ONLY";
+ case PROGRAM_ADDRESS:
+ return "ADDR";
+ case PROGRAM_SAMPLER:
+ return "SAMPLER";
+ case PROGRAM_UNDEFINED:
+ return "UNDEFINED";
+ default:
+ {
+ static char s[20];
+ snprintf(s, sizeof(s), "FILE%u", f);
+ return s;
+ }
+ }
+}
+
+
+/**
+ * Return ARB_v/f_prog-style input attrib string.
+ */
+static const char *
+arb_input_attrib_string(GLint index, GLenum progType)
+{
+ /*
+ * These strings should match the VERT_ATTRIB_x and FRAG_ATTRIB_x tokens.
+ */
+ const char *vertAttribs[] = {
+ "vertex.position",
+ "vertex.weight",
+ "vertex.normal",
+ "vertex.color.primary",
+ "vertex.color.secondary",
+ "vertex.fogcoord",
+ "vertex.(six)",
+ "vertex.(seven)",
+ "vertex.texcoord[0]",
+ "vertex.texcoord[1]",
+ "vertex.texcoord[2]",
+ "vertex.texcoord[3]",
+ "vertex.texcoord[4]",
+ "vertex.texcoord[5]",
+ "vertex.texcoord[6]",
+ "vertex.texcoord[7]",
+ "vertex.attrib[0]",
+ "vertex.attrib[1]",
+ "vertex.attrib[2]",
+ "vertex.attrib[3]",
+ "vertex.attrib[4]",
+ "vertex.attrib[5]",
+ "vertex.attrib[6]",
+ "vertex.attrib[7]",
+ "vertex.attrib[8]",
+ "vertex.attrib[9]",
+ "vertex.attrib[10]",
+ "vertex.attrib[11]",
+ "vertex.attrib[12]",
+ "vertex.attrib[13]",
+ "vertex.attrib[14]",
+ "vertex.attrib[15]"
+ };
+ const char *fragAttribs[] = {
+ "fragment.position",
+ "fragment.color.primary",
+ "fragment.color.secondary",
+ "fragment.fogcoord",
+ "fragment.texcoord[0]",
+ "fragment.texcoord[1]",
+ "fragment.texcoord[2]",
+ "fragment.texcoord[3]",
+ "fragment.texcoord[4]",
+ "fragment.texcoord[5]",
+ "fragment.texcoord[6]",
+ "fragment.texcoord[7]",
+ "fragment.varying[0]",
+ "fragment.varying[1]",
+ "fragment.varying[2]",
+ "fragment.varying[3]",
+ "fragment.varying[4]",
+ "fragment.varying[5]",
+ "fragment.varying[6]",
+ "fragment.varying[7]"
+ };
+
+ /* sanity checks */
+ assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0);
+ assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0);
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert((unsigned int)index < sizeof(vertAttribs) / sizeof(vertAttribs[0]));
+ return vertAttribs[index];
+ }
+ else {
+ assert((unsigned int)index < sizeof(fragAttribs) / sizeof(fragAttribs[0]));
+ return fragAttribs[index];
+ }
+}
+
+
+/**
+ * Print a vertex program's InputsRead field in human-readable format.
+ * For debugging.
+ */
+void
+_mesa_print_vp_inputs(GLbitfield inputs)
+{
+ printf("VP Inputs 0x%x: \n", inputs);
+ while (inputs) {
+ GLint attr = ffs(inputs) - 1;
+ const char *name = arb_input_attrib_string(attr,
+ GL_VERTEX_PROGRAM_ARB);
+ printf(" %d: %s\n", attr, name);
+ inputs &= ~(1 << attr);
+ }
+}
+
+
+/**
+ * Print a fragment program's InputsRead field in human-readable format.
+ * For debugging.
+ */
+void
+_mesa_print_fp_inputs(GLbitfield inputs)
+{
+ printf("FP Inputs 0x%x: \n", inputs);
+ while (inputs) {
+ GLint attr = ffs(inputs) - 1;
+ const char *name = arb_input_attrib_string(attr,
+ GL_FRAGMENT_PROGRAM_ARB);
+ printf(" %d: %s\n", attr, name);
+ inputs &= ~(1 << attr);
+ }
+}
+
+
+#if 0
+/**
+ * Return ARB_v/f_prog-style output attrib string.
+ */
+static const char *
+arb_output_attrib_string(GLint index, GLenum progType)
+{
+ /*
+ * These strings should match the VERT_RESULT_x and FRAG_RESULT_x tokens.
+ */
+ const char *vertResults[] = {
+ "result.position",
+ "result.color.primary",
+ "result.color.secondary",
+ "result.fogcoord",
+ "result.texcoord[0]",
+ "result.texcoord[1]",
+ "result.texcoord[2]",
+ "result.texcoord[3]",
+ "result.texcoord[4]",
+ "result.texcoord[5]",
+ "result.texcoord[6]",
+ "result.texcoord[7]",
+ "result.varying[0]",
+ "result.varying[1]",
+ "result.varying[2]",
+ "result.varying[3]",
+ "result.varying[4]",
+ "result.varying[5]",
+ "result.varying[6]",
+ "result.varying[7]"
+ };
+ const char *fragResults[] = {
+ "result.color",
+ "result.color(half)",
+ "result.depth",
+ "result.color[0]",
+ "result.color[1]",
+ "result.color[2]",
+ "result.color[3]"
+ };
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert(index < sizeof(vertResults) / sizeof(vertResults[0]));
+ return vertResults[index];
+ }
+ else {
+ assert(index < sizeof(fragResults) / sizeof(fragResults[0]));
+ return fragResults[index];
+ }
+}
+#endif
+
+/**
+ * Return string representation of the given register.
+ * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
+ * by the ARB/NV program languages so we've taken some liberties here.
+ * \param f the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
+ * \param index number of the register in the register file
+ * \param mode the output format/mode/style
+ * \param prog pointer to containing program
+ */
+static const char *
+reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
+ GLboolean relAddr, const struct gl_program *prog)
+{
+ static char str[100];
+ const char *addr = relAddr ? "ADDR+" : "";
+
+ str[0] = 0;
+
+ switch (mode) {
+ case PROG_PRINT_DEBUG:
+ sprintf(str, "%s[%s%d]", file_string(f, mode), addr, index);
+ break;
+ case PROG_PRINT_ARB:
+#if 0
+ switch (f) {
+ case PROGRAM_INPUT:
+ sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_OUTPUT:
+ sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_TEMPORARY:
+ sprintf(str, "temp%d", index);
+ break;
+ case PROGRAM_ENV_PARAM:
+ sprintf(str, "program.env[%s%d]", addr, index);
+ break;
+ case PROGRAM_LOCAL_PARAM:
+ sprintf(str, "program.local[%s%d]", addr, index);
+ break;
+ case PROGRAM_VARYING: /* extension */
+ sprintf(str, "varying[%s%d]", addr, index);
+ break;
+ case PROGRAM_CONSTANT: /* extension */
+ sprintf(str, "constant[%s%d]", addr, index);
+ break;
+ case PROGRAM_UNIFORM: /* extension */
+ sprintf(str, "uniform[%s%d]", addr, index);
+ break;
+ case PROGRAM_STATE_VAR:
+ {
+ struct gl_program_parameter *param
+ = prog->Parameters->Parameters + index;
+ char *state = _mesa_program_state_string(param->StateIndexes);
+ sprintf(str, "%s", state);
+ free(state);
+ }
+ break;
+ case PROGRAM_ADDRESS:
+ sprintf(str, "A%d", index);
+ break;
+ default:
+ _mesa_problem(NULL, "bad file in reg_string()");
+ }
+ break;
+#else
+ assert(0);
+ break;
+#endif
+
+ case PROG_PRINT_NV:
+ switch (f) {
+ case PROGRAM_INPUT:
+ if (prog->Target == GL_VERTEX_PROGRAM_ARB)
+ sprintf(str, "v[%d]", index);
+ else
+ sprintf(str, "f[%d]", index);
+ break;
+ case PROGRAM_OUTPUT:
+ sprintf(str, "o[%d]", index);
+ break;
+ case PROGRAM_TEMPORARY:
+ sprintf(str, "R%d", index);
+ break;
+ case PROGRAM_ENV_PARAM:
+ sprintf(str, "c[%d]", index);
+ break;
+ case PROGRAM_VARYING: /* extension */
+ sprintf(str, "varying[%s%d]", addr, index);
+ break;
+ case PROGRAM_UNIFORM: /* extension */
+ sprintf(str, "uniform[%s%d]", addr, index);
+ break;
+ case PROGRAM_CONSTANT: /* extension */
+ sprintf(str, "constant[%s%d]", addr, index);
+ break;
+ case PROGRAM_STATE_VAR: /* extension */
+ sprintf(str, "state[%s%d]", addr, index);
+ break;
+ default:
+ _mesa_problem(NULL, "bad file in reg_string()");
+ }
+ break;
+
+ default:
+ _mesa_problem(NULL, "bad mode in reg_string()");
+ }
+
+ return str;
+}
+
+
+/**
+ * Return a string representation of the given swizzle word.
+ * If extended is true, use extended (comma-separated) format.
+ * \param swizzle the swizzle field
+ * \param negateBase 4-bit negation vector
+ * \param extended if true, also allow 0, 1 values
+ */
+const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateMask, GLboolean extended)
+{
+ static const char swz[] = "xyzw01!?"; /* See SWIZZLE_x definitions */
+ static char s[20];
+ GLuint i = 0;
+
+ if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0)
+ return ""; /* no swizzle/negation */
+
+ if (!extended)
+ s[i++] = '.';
+
+ if (negateMask & NEGATE_X)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 0)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateMask & NEGATE_Y)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 1)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateMask & NEGATE_Z)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 2)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateMask & NEGATE_W)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 3)];
+
+ s[i] = 0;
+ return s;
+}
+
+
+void
+_mesa_print_swizzle(GLuint swizzle)
+{
+ if (swizzle == SWIZZLE_XYZW) {
+ printf(".xyzw\n");
+ }
+ else {
+ const char *s = _mesa_swizzle_string(swizzle, 0, 0);
+ printf("%s\n", s);
+ }
+}
+
+
+const char *
+_mesa_writemask_string(GLuint writeMask)
+{
+ static char s[10];
+ GLuint i = 0;
+
+ if (writeMask == WRITEMASK_XYZW)
+ return "";
+
+ s[i++] = '.';
+ if (writeMask & WRITEMASK_X)
+ s[i++] = 'x';
+ if (writeMask & WRITEMASK_Y)
+ s[i++] = 'y';
+ if (writeMask & WRITEMASK_Z)
+ s[i++] = 'z';
+ if (writeMask & WRITEMASK_W)
+ s[i++] = 'w';
+
+ s[i] = 0;
+ return s;
+}
+
+
+const char *
+_mesa_condcode_string(GLuint condcode)
+{
+ switch (condcode) {
+ case COND_GT: return "GT";
+ case COND_EQ: return "EQ";
+ case COND_LT: return "LT";
+ case COND_UN: return "UN";
+ case COND_GE: return "GE";
+ case COND_LE: return "LE";
+ case COND_NE: return "NE";
+ case COND_TR: return "TR";
+ case COND_FL: return "FL";
+ default: return "cond???";
+ }
+}
+
+
+static void
+fprint_dst_reg(FILE * f,
+ const struct prog_dst_register *dstReg,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ fprintf(f, "%s%s",
+ reg_string((gl_register_file) dstReg->File,
+ dstReg->Index, mode, dstReg->RelAddr, prog),
+ _mesa_writemask_string(dstReg->WriteMask));
+
+ if (dstReg->CondMask != COND_TR) {
+ fprintf(f, " (%s.%s)",
+ _mesa_condcode_string(dstReg->CondMask),
+ _mesa_swizzle_string(dstReg->CondSwizzle,
+ GL_FALSE, GL_FALSE));
+ }
+
+#if 0
+ fprintf(f, "%s[%d]%s",
+ file_string((gl_register_file) dstReg->File, mode),
+ dstReg->Index,
+ _mesa_writemask_string(dstReg->WriteMask));
+#endif
+}
+
+
+static void
+fprint_src_reg(FILE *f,
+ const struct prog_src_register *srcReg,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ const char *abs = srcReg->Abs ? "|" : "";
+
+ fprintf(f, "%s%s%s%s",
+ abs,
+ reg_string((gl_register_file) srcReg->File,
+ srcReg->Index, mode, srcReg->RelAddr, prog),
+ _mesa_swizzle_string(srcReg->Swizzle,
+ srcReg->Negate, GL_FALSE),
+ abs);
+#if 0
+ fprintf(f, "%s[%d]%s",
+ file_string((gl_register_file) srcReg->File, mode),
+ srcReg->Index,
+ _mesa_swizzle_string(srcReg->Swizzle,
+ srcReg->Negate, GL_FALSE));
+#endif
+}
+
+
+static void
+fprint_comment(FILE *f, const struct prog_instruction *inst)
+{
+ if (inst->Comment)
+ fprintf(f, "; # %s\n", inst->Comment);
+ else
+ fprintf(f, ";\n");
+}
+
+
+static void
+fprint_alu_instruction(FILE *f,
+ const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ GLuint j;
+
+ fprintf(f, "%s", opcode_string);
+ if (inst->CondUpdate)
+ fprintf(f, ".C");
+
+ /* frag prog only */
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ fprintf(f, "_SAT");
+
+ fprintf(f, " ");
+ if (inst->DstReg.File != PROGRAM_UNDEFINED) {
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ }
+ else {
+ fprintf(f, " ???");
+ }
+
+ if (numRegs > 0)
+ fprintf(f, ", ");
+
+ for (j = 0; j < numRegs; j++) {
+ fprint_src_reg(f, inst->SrcReg + j, mode, prog);
+ if (j + 1 < numRegs)
+ fprintf(f, ", ");
+ }
+
+ fprint_comment(f, inst);
+}
+
+
+void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs)
+{
+ fprint_alu_instruction(stderr, inst, opcode_string,
+ numRegs, PROG_PRINT_DEBUG, NULL);
+}
+
+
+/**
+ * Print a single vertex/fragment program instruction.
+ */
+GLint
+_mesa_fprint_instruction_opt(FILE *f,
+ const struct prog_instruction *inst,
+ GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ GLint i;
+
+ if (inst->Opcode == OPCODE_ELSE ||
+ inst->Opcode == OPCODE_ENDIF ||
+ inst->Opcode == OPCODE_ENDLOOP ||
+ inst->Opcode == OPCODE_ENDSUB) {
+ indent -= 3;
+ }
+ for (i = 0; i < indent; i++) {
+ fprintf(f, " ");
+ }
+
+ switch (inst->Opcode) {
+ case OPCODE_PRINT:
+ fprintf(f, "PRINT '%s'", (char *) inst->Data);
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ fprintf(f, ", ");
+ fprintf(f, "%s[%d]%s",
+ file_string((gl_register_file) inst->SrcReg[0].File,
+ mode),
+ inst->SrcReg[0].Index,
+ _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+ inst->SrcReg[0].Negate, GL_FALSE));
+ }
+ if (inst->Comment)
+ fprintf(f, " # %s", inst->Comment);
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_SWZ:
+ fprintf(f, "SWZ");
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ fprintf(f, "_SAT");
+ fprintf(f, " ");
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ fprintf(f, ", %s[%d], %s",
+ file_string((gl_register_file) inst->SrcReg[0].File,
+ mode),
+ inst->SrcReg[0].Index,
+ _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+ inst->SrcReg[0].Negate, GL_TRUE));
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_TEX:
+ case OPCODE_TXP:
+ case OPCODE_TXL:
+ case OPCODE_TXB:
+ fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ fprintf(f, "_SAT");
+ fprintf(f, " ");
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ fprintf(f, ", ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ fprintf(f, ", texture[%d], ", inst->TexSrcUnit);
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX: fprintf(f, "1D"); break;
+ case TEXTURE_2D_INDEX: fprintf(f, "2D"); break;
+ case TEXTURE_3D_INDEX: fprintf(f, "3D"); break;
+ case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE"); break;
+ case TEXTURE_RECT_INDEX: fprintf(f, "RECT"); break;
+ case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break;
+ case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break;
+ default:
+ ;
+ }
+ if (inst->TexShadow)
+ fprintf(f, " SHADOW");
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_KIL:
+ fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+ fprintf(f, " ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_KIL_NV:
+ fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+ fprintf(f, " ");
+ fprintf(f, "%s.%s",
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+ GL_FALSE, GL_FALSE));
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_ARL:
+ fprintf(f, "ARL ");
+ fprint_dst_reg(f, &inst->DstReg, mode, prog);
+ fprintf(f, ", ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_BRA:
+ fprintf(f, "BRA %d (%s%s)",
+ inst->BranchTarget,
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+ fprint_comment(f, inst);
+ break;
+ case OPCODE_IF:
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ /* Use ordinary register */
+ fprintf(f, "IF ");
+ fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+ fprintf(f, "; ");
+ }
+ else {
+ /* Use cond codes */
+ fprintf(f, "IF (%s%s);",
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+ 0, GL_FALSE));
+ }
+ fprintf(f, " # (if false, goto %d)", inst->BranchTarget);
+ fprint_comment(f, inst);
+ return indent + 3;
+ case OPCODE_ELSE:
+ fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget);
+ return indent + 3;
+ case OPCODE_ENDIF:
+ fprintf(f, "ENDIF;\n");
+ break;
+ case OPCODE_BGNLOOP:
+ fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget);
+ return indent + 3;
+ case OPCODE_ENDLOOP:
+ fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget);
+ break;
+ case OPCODE_BRK:
+ case OPCODE_CONT:
+ fprintf(f, "%s (%s%s); # (goto %d)",
+ _mesa_opcode_string(inst->Opcode),
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+ inst->BranchTarget);
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_BGNSUB:
+ if (mode == PROG_PRINT_NV) {
+ fprintf(f, "%s:\n", inst->Comment); /* comment is label */
+ return indent;
+ }
+ else {
+ fprintf(f, "BGNSUB");
+ fprint_comment(f, inst);
+ return indent + 3;
+ }
+ case OPCODE_ENDSUB:
+ if (mode == PROG_PRINT_DEBUG) {
+ fprintf(f, "ENDSUB");
+ fprint_comment(f, inst);
+ }
+ break;
+ case OPCODE_CAL:
+ if (mode == PROG_PRINT_NV) {
+ fprintf(f, "CAL %s; # (goto %d)\n", inst->Comment, inst->BranchTarget);
+ }
+ else {
+ fprintf(f, "CAL %u", inst->BranchTarget);
+ fprint_comment(f, inst);
+ }
+ break;
+ case OPCODE_RET:
+ fprintf(f, "RET (%s%s)",
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+ fprint_comment(f, inst);
+ break;
+
+ case OPCODE_END:
+ fprintf(f, "END\n");
+ break;
+ case OPCODE_NOP:
+ if (mode == PROG_PRINT_DEBUG) {
+ fprintf(f, "NOP");
+ fprint_comment(f, inst);
+ }
+ else if (inst->Comment) {
+ /* ARB/NV extensions don't have NOP instruction */
+ fprintf(f, "# %s\n", inst->Comment);
+ }
+ break;
+ /* XXX may need other special-case instructions */
+ default:
+ if (inst->Opcode < MAX_OPCODE) {
+ /* typical alu instruction */
+ fprint_alu_instruction(f, inst,
+ _mesa_opcode_string(inst->Opcode),
+ _mesa_num_inst_src_regs(inst->Opcode),
+ mode, prog);
+ }
+ else {
+ fprint_alu_instruction(f, inst,
+ _mesa_opcode_string(inst->Opcode),
+ 3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
+ mode, prog);
+ }
+ break;
+ }
+ return indent;
+}
+
+
+GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst,
+ GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog);
+}
+
+
+void
+_mesa_print_instruction(const struct prog_instruction *inst)
+{
+ /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
+ _mesa_fprint_instruction_opt(stdout, inst, 0, PROG_PRINT_DEBUG, NULL);
+}
+
+#if 0
+/**
+ * Print program, with options.
+ */
+void
+_mesa_fprint_program_opt(FILE *f,
+ const struct gl_program *prog,
+ gl_prog_print_mode mode,
+ GLboolean lineNumbers)
+{
+ GLuint i, indent = 0;
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ if (mode == PROG_PRINT_ARB)
+ fprintf(f, "!!ARBvp1.0\n");
+ else if (mode == PROG_PRINT_NV)
+ fprintf(f, "!!VP1.0\n");
+ else
+ fprintf(f, "# Vertex Program/Shader %u\n", prog->Id);
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ case GL_FRAGMENT_PROGRAM_NV:
+ if (mode == PROG_PRINT_ARB)
+ fprintf(f, "!!ARBfp1.0\n");
+ else if (mode == PROG_PRINT_NV)
+ fprintf(f, "!!FP1.0\n");
+ else
+ fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
+ break;
+ }
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ if (lineNumbers)
+ fprintf(f, "%3d: ", i);
+ indent = _mesa_fprint_instruction_opt(f, prog->Instructions + i,
+ indent, mode, prog);
+ }
+}
+
+
+/**
+ * Print program to stderr, default options.
+ */
+void
+_mesa_print_program(const struct gl_program *prog)
+{
+ _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
+}
+
+/**
+ * Return binary representation of 64-bit value (as a string).
+ * Insert a comma to separate each group of 8 bits.
+ * Note we return a pointer to local static storage so this is not
+ * re-entrant, etc.
+ * XXX move to imports.[ch] if useful elsewhere.
+ */
+static const char *
+binary(GLbitfield64 val)
+{
+ static char buf[80];
+ GLint i, len = 0;
+ for (i = 63; i >= 0; --i) {
+ if (val & (1ULL << i))
+ buf[len++] = '1';
+ else if (len > 0 || i == 0)
+ buf[len++] = '0';
+ if (len > 0 && ((i-1) % 8) == 7)
+ buf[len++] = ',';
+ }
+ buf[len] = '\0';
+ return buf;
+}
+
+
+/**
+ * Print all of a program's parameters/fields to given file.
+ */
+static void
+_mesa_fprint_program_parameters(FILE *f,
+ GLcontext *ctx,
+ const struct gl_program *prog)
+{
+ GLuint i;
+
+ fprintf(f, "InputsRead: 0x%x (0b%s)\n",
+ prog->InputsRead, binary(prog->InputsRead));
+ fprintf(f, "OutputsWritten: 0x%llx (0b%s)\n",
+ prog->OutputsWritten, binary(prog->OutputsWritten));
+ fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
+ fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
+ fprintf(f, "NumParameters=%d\n", prog->NumParameters);
+ fprintf(f, "NumAttributes=%d\n", prog->NumAttributes);
+ fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs);
+ fprintf(f, "SamplersUsed: 0x%x (0b%s)\n",
+ prog->SamplersUsed, binary(prog->SamplersUsed));
+ fprintf(f, "Samplers=[ ");
+ for (i = 0; i < MAX_SAMPLERS; i++) {
+ fprintf(f, "%d ", prog->SamplerUnits[i]);
+ }
+ fprintf(f, "]\n");
+
+ _mesa_load_state_parameters(ctx, prog->Parameters);
+
+#if 0
+ fprintf(f, "Local Params:\n");
+ for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
+ const GLfloat *p = prog->LocalParams[i];
+ fprintf(f, "%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
+ }
+#endif
+ _mesa_print_parameter_list(prog->Parameters);
+}
+
+
+/**
+ * Print all of a program's parameters/fields to stderr.
+ */
+void
+_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
+{
+ _mesa_fprint_program_parameters(stderr, ctx, prog);
+}
+
+
+/**
+ * Print a program parameter list to given file.
+ */
+static void
+_mesa_fprint_parameter_list(FILE *f,
+ const struct gl_program_parameter_list *list)
+{
+ const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
+ GLuint i;
+
+ if (!list)
+ return;
+
+ if (0)
+ fprintf(f, "param list %p\n", (void *) list);
+ fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags);
+ for (i = 0; i < list->NumParameters; i++){
+ struct gl_program_parameter *param = list->Parameters + i;
+ const GLfloat *v = list->ParameterValues[i];
+ fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}",
+ i, param->Size,
+ file_string(list->Parameters[i].Type, mode),
+ param->Name, v[0], v[1], v[2], v[3]);
+ if (param->Flags & PROG_PARAM_BIT_CENTROID)
+ fprintf(f, " Centroid");
+ if (param->Flags & PROG_PARAM_BIT_INVARIANT)
+ fprintf(f, " Invariant");
+ if (param->Flags & PROG_PARAM_BIT_FLAT)
+ fprintf(f, " Flat");
+ if (param->Flags & PROG_PARAM_BIT_LINEAR)
+ fprintf(f, " Linear");
+ fprintf(f, "\n");
+ }
+}
+
+
+/**
+ * Print a program parameter list to stderr.
+ */
+void
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
+{
+ _mesa_fprint_parameter_list(stderr, list);
+}
+
+
+/**
+ * Write shader and associated info to a file.
+ */
+void
+_mesa_write_shader_to_file(const struct gl_shader *shader)
+{
+ const char *type;
+ char filename[100];
+ FILE *f;
+
+ if (shader->Type == GL_FRAGMENT_SHADER)
+ type = "frag";
+ else
+ type = "vert";
+
+ snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+ f = fopen(filename, "w");
+ if (!f) {
+ fprintf(stderr, "Unable to open %s for writing\n", filename);
+ return;
+ }
+
+ fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
+ fputs(shader->Source, f);
+ fprintf(f, "\n");
+
+ fprintf(f, "/* Compile status: %s */\n",
+ shader->CompileStatus ? "ok" : "fail");
+ if (!shader->CompileStatus) {
+ fprintf(f, "/* Log Info: */\n");
+ fputs(shader->InfoLog, f);
+ }
+ else {
+ fprintf(f, "/* GPU code */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
+ fprintf(f, "*/\n");
+ fprintf(f, "/* Parameters / constants */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_parameter_list(f, shader->Program->Parameters);
+ fprintf(f, "*/\n");
+ }
+
+ fclose(f);
+}
+
+
+/**
+ * Append the shader's uniform info/values to the shader log file.
+ * The log file will typically have been created by the
+ * _mesa_write_shader_to_file function.
+ */
+void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+ const struct gl_program *prog)
+{
+ const char *type;
+ char filename[100];
+ FILE *f;
+
+ if (shader->Type == GL_FRAGMENT_SHADER)
+ type = "frag";
+ else
+ type = "vert";
+
+ snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+ f = fopen(filename, "a"); /* append */
+ if (!f) {
+ fprintf(stderr, "Unable to open %s for appending\n", filename);
+ return;
+ }
+
+ fprintf(f, "/* First-draw parameters / constants */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_parameter_list(f, prog->Parameters);
+ fprintf(f, "*/\n");
+
+ fclose(f);
+}
+#endif
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.3
+ *
+ * Copyright (C) 1999-2007 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.
+ */
+
+
+#ifndef PROG_PRINT_H
+#define PROG_PRINT_H
+
+
+/**
+ * The output style to use when printing programs.
+ */
+typedef enum {
+ PROG_PRINT_ARB,
+ PROG_PRINT_NV,
+ PROG_PRINT_DEBUG
+} gl_prog_print_mode;
+
+
+extern void
+_mesa_print_vp_inputs(GLbitfield inputs);
+
+extern void
+_mesa_print_fp_inputs(GLbitfield inputs);
+
+extern const char *
+_mesa_condcode_string(GLuint condcode);
+
+extern const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
+
+const char *
+_mesa_writemask_string(GLuint writeMask);
+
+extern void
+_mesa_print_swizzle(GLuint swizzle);
+
+extern void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs);
+
+extern void
+_mesa_print_instruction(const struct prog_instruction *inst);
+
+extern GLint
+_mesa_fprint_instruction_opt(FILE *f,
+ const struct prog_instruction *inst,
+ GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
+
+extern GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
+
+extern void
+_mesa_print_program(const struct gl_program *prog);
+
+extern void
+_mesa_fprint_program_opt(FILE *f,
+ const struct gl_program *prog, gl_prog_print_mode mode,
+ GLboolean lineNumbers);
+
+#if 0
+extern void
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list);
+
+extern void
+_mesa_write_shader_to_file(const struct gl_shader *shader);
+
+extern void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+ const struct gl_program *prog);
+#endif
+
+
+#endif /* PROG_PRINT_H */
--- /dev/null
+/*
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ * 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 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.
+ */
+
+#include <GL/gl.h>
+#include "main/mtypes.h"
+
+/**
+ * Based on gl_shader in Mesa's mtypes.h.
+ */
+struct glsl_shader {
+ GLenum Type;
+ GLuint Name;
+ GLint RefCount;
+ GLboolean DeletePending;
+ GLboolean CompileStatus;
+ const GLchar *Source; /**< Source code string */
+ size_t SourceLen;
+ GLchar *InfoLog;
+
+ struct exec_list ir;
+ struct glsl_symbol_table *symbols;
+};
+
+
+typedef int gl_state_index;
+#define STATE_LENGTH 5
+
+/**
+ * Program parameter.
+ * Used by shaders/programs for uniforms, constants, varying vars, etc.
+ */
+struct gl_program_parameter
+{
+ const char *Name; /**< Null-terminated string */
+ gl_register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */
+ GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
+ /**
+ * Number of components (1..4), or more.
+ * If the number of components is greater than 4,
+ * this parameter is part of a larger uniform like a GLSL matrix or array.
+ * The next program parameter's Size will be Size-4 of this parameter.
+ */
+ GLuint Size;
+ GLboolean Used; /**< Helper flag for GLSL uniform tracking */
+ GLboolean Initialized; /**< Has the ParameterValue[] been set? */
+ GLbitfield Flags; /**< Bitmask of PROG_PARAM_*_BIT */
+ /**
+ * A sequence of STATE_* tokens and integers to identify GL state.
+ */
+ gl_state_index StateIndexes[STATE_LENGTH];
+};
+
+
+/**
+ * List of gl_program_parameter instances.
+ */
+struct gl_program_parameter_list
+{
+ GLuint Size; /**< allocated size of Parameters, ParameterValues */
+ GLuint NumParameters; /**< number of parameters in arrays */
+ struct gl_program_parameter *Parameters; /**< Array [Size] */
+ GLfloat (*ParameterValues)[4]; /**< Array [Size] of GLfloat[4] */
+ GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
+ might invalidate ParameterValues[] */
+};
+
+
+/**
+ * Shader program uniform variable.
+ * The glGetUniformLocation() and glUniform() commands will use this
+ * information.
+ * Note that a uniform such as "binormal" might be used in both the
+ * vertex shader and the fragment shader. When glUniform() is called to
+ * set the uniform's value, it must be updated in both the vertex and
+ * fragment shaders. The uniform may be in different locations in the
+ * two shaders so we keep track of that here.
+ */
+struct gl_uniform
+{
+ const char *Name; /**< Null-terminated string */
+ GLint VertPos;
+ GLint FragPos;
+ GLboolean Initialized; /**< For debug. Has this uniform been set? */
+#if 0
+ GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
+ GLuint Size; /**< Number of components (1..4) */
+#endif
+};
+
+
+/**
+ * List of gl_uniforms
+ */
+struct gl_uniform_list
+{
+ GLuint Size; /**< allocated size of Uniforms array */
+ GLuint NumUniforms; /**< number of uniforms in the array */
+ struct gl_uniform *Uniforms; /**< Array [Size] */
+};
+
+
+/**
+ * Based on gl_shader_program in Mesa's mtypes.h.
+ */
+struct glsl_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 glsl_shader **Shaders; /**< List of attached the shaders */
+
+ /**
+ * Per-stage shaders resulting from the first stage of linking.
+ */
+ /*@{*/
+ unsigned _NumLinkedShaders;
+ struct glsl_shader **_LinkedShaders;
+ /*@}*/
+
+ /** User-defined attribute bindings (glBindAttribLocation) */
+ struct gl_program_parameter_list *Attributes;
+
+ /* post-link info: */
+ 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;
+};
+
+extern void
+link_shaders(struct glsl_program *prog);
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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 <cstdlib>
+#include <cstring>
+#include <assert.h>
+#include "s_expression.h"
+
+s_symbol::s_symbol(const char *tmp)
+{
+ this->str = talloc_strdup (this, tmp);
+ assert(this->str != NULL);
+}
+
+s_list::s_list()
+{
+}
+
+unsigned
+s_list::length() const
+{
+ unsigned i = 0;
+ foreach_iter(exec_list_iterator, it, this->subexpressions) {
+ i++;
+ }
+ return i;
+}
+
+static s_expression *
+read_atom(void *ctx, const char *& src)
+{
+ char buf[101];
+ int n;
+ if (sscanf(src, " %100[^( \v\t\r\n)]%n", buf, &n) != 1)
+ return NULL; // no atom
+ src += n;
+
+ // Check if the atom is a number.
+ char *float_end = NULL;
+ double f = strtod(buf, &float_end);
+ if (float_end != buf) {
+ char *int_end = NULL;
+ int i = strtol(buf, &int_end, 10);
+ // If strtod matched more characters, it must have a decimal part
+ if (float_end > int_end)
+ return new(ctx) s_float(f);
+
+ return new(ctx) s_int(i);
+ }
+ // Not a number; return a symbol.
+ return new(ctx) s_symbol(buf);
+}
+
+s_expression *
+s_expression::read_expression(void *ctx, const char *&src)
+{
+ assert(src != NULL);
+
+ s_expression *atom = read_atom(ctx, src);
+ if (atom != NULL)
+ return atom;
+
+ char c;
+ int n;
+ if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') {
+ src += n;
+
+ s_list *list = new(ctx) s_list;
+ s_expression *expr;
+
+ while ((expr = read_expression(ctx, src)) != NULL) {
+ list->subexpressions.push_tail(expr);
+ }
+ if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') {
+ printf("Unclosed expression (check your parenthesis).\n");
+ return NULL;
+ }
+ src += n;
+ return list;
+ }
+ return NULL;
+}
+
+void s_int::print()
+{
+ printf("%d", this->val);
+}
+
+void s_float::print()
+{
+ printf("%f", this->val);
+}
+
+void s_symbol::print()
+{
+ printf("%s", this->str);
+}
+
+void s_list::print()
+{
+ printf("(");
+ foreach_iter(exec_list_iterator, it, this->subexpressions) {
+ s_expression *expr = (s_expression*) it.get();
+ expr->print();
+ printf(" ");
+ }
+ printf(")");
+}
+
--- /dev/null
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#pragma once
+#ifndef S_EXPRESSION_H
+#define S_EXPRESSION_H
+
+#include "list.h"
+
+#define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \
+ : NULL
+#define SX_AS_LIST(x) SX_AS_(list, x)
+#define SX_AS_SYMBOL(x) SX_AS_(symbol, x)
+#define SX_AS_NUMBER(x) SX_AS_(number, x)
+#define SX_AS_INT(x) SX_AS_(int, x)
+
+/* For our purposes, S-Expressions are:
+ * - <int>
+ * - <float>
+ * - symbol
+ * - (expr1 expr2 ... exprN) where exprN is an S-Expression
+ *
+ * Unlike LISP/Scheme, we do not support (foo . bar) pairs.
+ */
+class s_expression : public exec_node
+{
+public:
+ /**
+ * Read an S-Expression from the given string.
+ * Advances the supplied pointer to just after the expression read.
+ *
+ * Any allocation will be performed with 'ctx' as the talloc owner.
+ */
+ static s_expression *read_expression(void *ctx, const char *&src);
+
+ /**
+ * Print out an S-Expression. Useful for debugging.
+ */
+ virtual void print() = 0;
+
+ virtual bool is_list() const { return false; }
+ virtual bool is_symbol() const { return false; }
+ virtual bool is_number() const { return false; }
+ virtual bool is_int() const { return false; }
+
+protected:
+ s_expression() { }
+};
+
+/* Atoms */
+
+class s_number : public s_expression
+{
+public:
+ bool is_number() const { return true; }
+
+ virtual float fvalue() = 0;
+
+protected:
+ s_number() { }
+};
+
+class s_int : public s_number
+{
+public:
+ s_int(int x) : val(x) { }
+
+ bool is_int() const { return true; }
+
+ float fvalue() { return float(this->val); }
+ int value() { return this->val; }
+
+ void print();
+
+private:
+ int val;
+};
+
+class s_float : public s_number
+{
+public:
+ s_float(float x) : val(x) { }
+
+ float fvalue() { return this->val; }
+
+ void print();
+
+private:
+ float val;
+};
+
+class s_symbol : public s_expression
+{
+public:
+ s_symbol(const char *);
+
+ bool is_symbol() const { return true; }
+
+ const char *value() { return this->str; }
+
+ void print();
+
+private:
+ char *str;
+};
+
+/* Lists of expressions: (expr1 ... exprN) */
+class s_list : public s_expression
+{
+public:
+ s_list();
+
+ virtual bool is_list() const { return true; }
+ unsigned length() const;
+
+ void print();
+
+ exec_list subexpressions;
+};
+
+#endif /* S_EXPRESSION_H */
--- /dev/null
+/*
+ * Copyright © 2008 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 "main/imports.h"
+#include "symbol_table.h"
+#include "hash_table.h"
+
+struct symbol {
+ /**
+ * Link to the next symbol in the table with the same name
+ *
+ * The linked list of symbols with the same name is ordered by scope
+ * from inner-most to outer-most.
+ */
+ struct symbol *next_with_same_name;
+
+
+ /**
+ * Link to the next symbol in the table with the same scope
+ *
+ * The linked list of symbols with the same scope is unordered. Symbols
+ * in this list my have unique names.
+ */
+ struct symbol *next_with_same_scope;
+
+
+ /**
+ * Header information for the list of symbols with the same name.
+ */
+ struct symbol_header *hdr;
+
+
+ /**
+ * Name space of the symbol
+ *
+ * Name space are arbitrary user assigned integers. No two symbols can
+ * exist in the same name space at the same scope level.
+ */
+ int name_space;
+
+
+ /**
+ * Arbitrary user supplied data.
+ */
+ void *data;
+
+ /** Scope depth where this symbol was defined. */
+ unsigned depth;
+};
+
+
+/**
+ */
+struct symbol_header {
+ /** Linkage in list of all headers in a given symbol table. */
+ struct symbol_header *next;
+
+ /** Symbol name. */
+ const char *name;
+
+ /** Linked list of symbols with the same name. */
+ struct symbol *symbols;
+};
+
+
+/**
+ * Element of the scope stack.
+ */
+struct scope_level {
+ /** Link to next (inner) scope level. */
+ struct scope_level *next;
+
+ /** Linked list of symbols with the same scope. */
+ struct symbol *symbols;
+};
+
+
+/**
+ *
+ */
+struct _mesa_symbol_table {
+ /** Hash table containing all symbols in the symbol table. */
+ struct hash_table *ht;
+
+ /** Top of scope stack. */
+ struct scope_level *current_scope;
+
+ /** List of all symbol headers in the table. */
+ struct symbol_header *hdr;
+
+ /** Current scope depth. */
+ unsigned depth;
+};
+
+
+struct _mesa_symbol_table_iterator {
+ /**
+ * Name space of symbols returned by this iterator.
+ */
+ int name_space;
+
+
+ /**
+ * Currently iterated symbol
+ *
+ * The next call to \c _mesa_symbol_table_iterator_get will return this
+ * value. It will also update this value to the value that should be
+ * returned by the next call.
+ */
+ struct symbol *curr;
+};
+
+
+static void
+check_symbol_table(struct _mesa_symbol_table *table)
+{
+#if 1
+ struct scope_level *scope;
+
+ for (scope = table->current_scope; scope != NULL; scope = scope->next) {
+ struct symbol *sym;
+
+ for (sym = scope->symbols
+ ; sym != NULL
+ ; sym = sym->next_with_same_name) {
+ const struct symbol_header *const hdr = sym->hdr;
+ struct symbol *sym2;
+
+ for (sym2 = hdr->symbols
+ ; sym2 != NULL
+ ; sym2 = sym2->next_with_same_name) {
+ assert(sym2->hdr == hdr);
+ }
+ }
+ }
+#endif
+}
+
+void
+_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = table->current_scope;
+ struct symbol *sym = scope->symbols;
+
+ table->current_scope = scope->next;
+ table->depth--;
+
+ free(scope);
+
+ while (sym != NULL) {
+ struct symbol *const next = sym->next_with_same_scope;
+ struct symbol_header *const hdr = sym->hdr;
+
+ assert(hdr->symbols == sym);
+
+ hdr->symbols = sym->next_with_same_name;
+
+ free(sym);
+
+ sym = next;
+ }
+
+ check_symbol_table(table);
+}
+
+
+void
+_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = calloc(1, sizeof(*scope));
+
+ scope->next = table->current_scope;
+ table->current_scope = scope;
+ table->depth++;
+}
+
+
+static struct symbol_header *
+find_symbol(struct _mesa_symbol_table *table, const char *name)
+{
+ return (struct symbol_header *) hash_table_find(table->ht, name);
+}
+
+
+struct _mesa_symbol_table_iterator *
+_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
+ struct symbol_header *const hdr = find_symbol(table, name);
+
+ iter->name_space = name_space;
+
+ if (hdr != NULL) {
+ struct symbol *sym;
+
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ iter->curr = sym;
+ break;
+ }
+ }
+ }
+
+ return iter;
+}
+
+
+void
+_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
+{
+ free(iter);
+}
+
+
+void *
+_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
+{
+ return (iter->curr == NULL) ? NULL : iter->curr->data;
+}
+
+
+int
+_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
+{
+ struct symbol_header *hdr;
+
+ if (iter->curr == NULL) {
+ return 0;
+ }
+
+ hdr = iter->curr->hdr;
+ iter->curr = iter->curr->next_with_same_name;
+
+ while (iter->curr != NULL) {
+ assert(iter->curr->hdr == hdr);
+
+ if ((iter->name_space == -1)
+ || (iter->curr->name_space == iter->name_space)) {
+ return 1;
+ }
+
+ iter->curr = iter->curr->next_with_same_name;
+ }
+
+ return 0;
+}
+
+
+/**
+ * Determine the scope "distance" of a symbol from the current scope
+ *
+ * \return
+ * A non-negative number for the number of scopes between the current scope
+ * and the scope where a symbol was defined. A value of zero means the current
+ * scope. A negative number if the symbol does not exist.
+ */
+int
+_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+ struct symbol *sym;
+
+ if (hdr != NULL) {
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ assert(sym->depth <= table->depth);
+ return sym->depth - table->depth;
+ }
+ }
+ }
+
+ return -1;
+}
+
+
+void *
+_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+
+ if (hdr != NULL) {
+ struct symbol *sym;
+
+
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ return sym->data;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+int
+_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name,
+ void *declaration)
+{
+ struct symbol_header *hdr;
+ struct symbol *sym;
+
+ check_symbol_table(table);
+
+ hdr = find_symbol(table, name);
+
+ check_symbol_table(table);
+
+ if (hdr == NULL) {
+ hdr = calloc(1, sizeof(*hdr));
+ hdr->name = name;
+
+ hash_table_insert(table->ht, hdr, name);
+ hdr->next = table->hdr;
+ table->hdr = hdr;
+ }
+
+ check_symbol_table(table);
+
+ /* If the symbol already exists in this namespace at this scope, it cannot
+ * be added to the table.
+ */
+ for (sym = hdr->symbols
+ ; (sym != NULL) && (sym->name_space != name_space)
+ ; sym = sym->next_with_same_name) {
+ /* empty */
+ }
+
+ if (sym && (sym->depth == table->depth))
+ return -1;
+
+ sym = calloc(1, sizeof(*sym));
+ sym->next_with_same_name = hdr->symbols;
+ sym->next_with_same_scope = table->current_scope->symbols;
+ sym->hdr = hdr;
+ sym->name_space = name_space;
+ sym->data = declaration;
+ sym->depth = table->depth;
+
+ assert(sym->hdr == hdr);
+
+ hdr->symbols = sym;
+ table->current_scope->symbols = sym;
+
+ check_symbol_table(table);
+ return 0;
+}
+
+
+struct _mesa_symbol_table *
+_mesa_symbol_table_ctor(void)
+{
+ struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
+
+ if (table != NULL) {
+ table->ht = hash_table_ctor(32, hash_table_string_hash,
+ hash_table_string_compare);
+
+ _mesa_symbol_table_push_scope(table);
+ }
+
+ return table;
+}
+
+
+void
+_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
+{
+ struct symbol_header *hdr;
+ struct symbol_header *next;
+
+ while (table->current_scope != NULL) {
+ _mesa_symbol_table_pop_scope(table);
+ }
+
+ for (hdr = table->hdr; hdr != NULL; hdr = next) {
+ next = hdr->next;
+ _mesa_free(hdr);
+ }
+
+ hash_table_dtor(table->ht);
+ free(table);
+}
--- /dev/null
+/*
+ * Copyright © 2008 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.
+ */
+#ifndef MESA_SYMBOL_TABLE_H
+#define MESA_SYMBOL_TABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _mesa_symbol_table;
+struct _mesa_symbol_table_iterator;
+
+extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
+
+extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
+
+extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
+ int name_space, const char *name, void *declaration);
+
+extern int _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+ int name_space, const char *name);
+
+extern void *_mesa_symbol_table_find_symbol(
+ struct _mesa_symbol_table *symtab, int name_space, const char *name);
+
+extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
+
+extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
+
+extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor(
+ struct _mesa_symbol_table *table, int name_space, const char *name);
+
+extern void _mesa_symbol_table_iterator_dtor(
+ struct _mesa_symbol_table_iterator *);
+
+extern void *_mesa_symbol_table_iterator_get(
+ struct _mesa_symbol_table_iterator *iter);
+
+extern int _mesa_symbol_table_iterator_next(
+ struct _mesa_symbol_table_iterator *iter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MESA_SYMBOL_TABLE_H */
--- /dev/null
+#version 120
+/* FAIL - array size type must be int */
+uniform vec4 [3.2] a;
--- /dev/null
+#version 120
+/* FAIL - array size type must be scalar */
+uniform vec4 [ivec4(3)] a;
--- /dev/null
+#version 120
+/* PASS */
+uniform vec4 [3] a;
--- /dev/null
+/* FAIL - array size type must be int */
+uniform vec4 a[3.2];
--- /dev/null
+/* FAIL - array size type must be scalar */
+uniform vec4 a[ivec4(3)];
--- /dev/null
+/* PASS */
+uniform vec4 a[3];
--- /dev/null
+/* FAIL - array size must be > 0 */
+uniform vec4 a[0];
--- /dev/null
+/* FAIL - array size must be > 0 */
+uniform vec4 a[-1];
--- /dev/null
+#version 120
+/* PASS */
+
+void main()
+{
+ vec4 a[2] = vec4 [2] (vec4(1.0), vec4(2.0));
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* FAIL - array constructors forbidden in GLSL 1.10
+ *
+ * This can also generate an error because the 'vec4[]' style syntax is
+ * illegal in GLSL 1.10.
+ */
+void main()
+{
+ vec4 a[2] = vec4 [2] (vec4(1.0), vec4(2.0));
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+#version 120
+/* PASS */
+
+void main()
+{
+ vec4 a[] = vec4 [] (vec4(1.0), vec4(2.0));
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+#version 120
+/* FAIL - array must have an implicit or explicit size */
+
+void main()
+{
+ vec4 a[];
+
+ a = vec4 [2] (vec4(1.0), vec4(2.0));
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+#version 120
+/* PASS */
+
+void main()
+{
+ vec4 a[2];
+
+ a = vec4 [] (vec4(1.0), vec4(2.0));
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* FAIL - attribute cannot have type int */
+attribute int i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have type ivec2 */
+attribute ivec2 i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have type ivec3 */
+attribute ivec3 i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have type ivec4 */
+attribute ivec4 i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have type bool */
+attribute bool i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have type bvec2 */
+attribute bvec2 i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have type bvec3 */
+attribute bvec3 i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have type bvec4 */
+attribute bvec4 i;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - attribute cannot have array type in GLSL 1.10 */
+attribute vec4 i[10];
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+#version 120
+/* FAIL - attribute cannot have array type in GLSL 1.20 */
+attribute vec4 i[10];
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+#version 130
+/* FAIL - attribute cannot have array type in GLSL 1.30 */
+attribute vec4 i[10];
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
--- /dev/null
+/* FAIL - :? condition is not bool scalar */
+
+uniform bvec4 a;
+
+void main()
+{
+ gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 1.0, 0.0, 1.0);
+}
--- /dev/null
+/* FAIL - :? condition is not bool scalar */
+
+uniform float a;
+
+void main()
+{
+ gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 1.0, 0.0, 1.0);
+}
--- /dev/null
+/* PASS */
+
+uniform bool a;
+
+void main()
+{
+ gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 1.0, 0.0, 1.0);
+}
--- /dev/null
+/* FAIL - type of second two operands must match */
+
+uniform bool a;
+
+void main()
+{
+ gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+}
--- /dev/null
+#version 120
+/* PASS */
+
+uniform bool a;
+uniform int b;
+
+void main()
+{
+ float x;
+
+ x = (a) ? 2.0 : b;
+ gl_Position = vec4(x);
+}
--- /dev/null
+/* PASS */
+
+void main()
+{
+ gl_Position = vec4(1.0, 1.0, 1.0, 0.0);;
+}
--- /dev/null
+/* FAIL - cannot construct samplers */
+void main()
+{
+ int i;
+
+ i = sampler2D(0);
+}
--- /dev/null
+/* FAIL - cannot construct a matrix from a matrix in GLSL 1.10 */
+
+uniform mat2 a;
+
+void main()
+{
+ mat2 b;
+
+ b = mat2(a);
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+#version 120
+/* FAIL - matrix must be only parameter to matrix constructor */
+
+uniform mat2 a;
+uniform float x;
+
+void main()
+{
+ mat2 b;
+
+ b = mat2(a, x);
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* FAIL - too few components supplied to constructor */
+
+uniform vec2 a;
+uniform float x;
+
+void main()
+{
+ mat2 b;
+
+ b = mat2(a, x);
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+#version 120
+/* PASS */
+
+uniform mat2 a;
+
+void main()
+{
+ mat2 b;
+
+ b = mat2(a);
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* PASS */
+
+uniform ivec2 a;
+uniform ivec2 b;
+
+void main()
+{
+ mat2 c;
+
+ c = mat2(a, b);
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* PASS */
+
+uniform float a;
+uniform float b;
+
+void main()
+{
+ ivec2 c;
+
+ c = ivec2(a, b);
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* PASS */
+
+uniform int a;
+uniform float b;
+uniform bool c;
+
+void main()
+{
+ float x;
+ int y;
+ bool z;
+
+ x = float(a);
+ x = float(b);
+ x = float(c);
+
+ y = int(a);
+ y = int(b);
+ y = int(c);
+
+ z = bool(a);
+ z = bool(b);
+ z = bool(c);
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* FAIL - no function named 'foo' exists */
+
+vec4 bar(float x, float y, float z, float w)
+{
+ vec4 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ v.w = w;
+ return v;
+}
+
+void main()
+{
+ gl_Position = foo(1.0, 1.0, 1.0, 0.0);
+}
--- /dev/null
+/* FAIL - no version of 'foo' matches the call to 'foo' */
+
+vec4 foo(float x, float y, float z, float w)
+{
+ vec4 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ v.w = w;
+ return v;
+}
+
+void main()
+{
+ gl_Position = foo(1.0, 1.0, 1.0);
+}
--- /dev/null
+/* PASS */
+
+vec4 foo(in float x, in float y, float z, float w)
+{
+ vec4 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ v.w = w;
+ return v;
+}
+
+void main()
+{
+ gl_Position = foo(1.0, 1.0, 1.0, 0.0);
+}
--- /dev/null
+/* FAIL - type mismatch in assignment */
+
+vec3 foo(float x, float y, float z)
+{
+ vec3 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ return v;
+}
+
+void main()
+{
+ gl_Position = foo(1.0, 1.0, 1.0);
+}
--- /dev/null
+/* PASS */
+
+vec4 foo(in float x, in float y, float z, float w)
+{
+ vec4 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ v.w = w;
+ return v;
+}
+
+vec4 foo(in float x)
+{
+ vec4 v;
+ v.x = x;
+ v.y = x;
+ v.z = x;
+ v.w = x;
+}
+
+void main()
+{
+ gl_Position = foo(1.0, 1.0, 1.0, 0.0);
+ gl_Position = foo(2.0);
+}
--- /dev/null
+/* FAIL - if-statement condition is not bool scalar */
+
+uniform bvec4 a;
+
+void main()
+{
+ if (a)
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
+}
--- /dev/null
+/* FAIL - if-statement condition is not bool scalar */
+
+uniform float a;
+
+void main()
+{
+ if (a)
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
+}
--- /dev/null
+/* PASS */
+
+uniform bool a;
+
+void main()
+{
+ if (a)
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
+}
--- /dev/null
+/* PASS */
+
+uniform bvec4 a;
+
+void main()
+{
+ if (a.x)
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
+}
--- /dev/null
+/* FAIL - non-square matrices are not available in GLSL 1.10 */
+
+void main()
+{
+ mat2x3 m;
+}
--- /dev/null
+/* FAIL - non-square matrices are not available in GLSL 1.10 */
+
+void main()
+{
+ mat2x4 m;
+}
--- /dev/null
+/* FAIL - non-square matrices are not available in GLSL 1.10 */
+
+void main()
+{
+ mat3x2 m;
+}
--- /dev/null
+/* FAIL - non-square matrices are not available in GLSL 1.10 */
+
+void main()
+{
+ mat3x4 m;
+}
--- /dev/null
+/* FAIL - non-square matrices are not available in GLSL 1.10 */
+
+void main()
+{
+ mat4x2 m;
+}
--- /dev/null
+/* FAIL - non-square matrices are not available in GLSL 1.10 */
+
+void main()
+{
+ mat4x3 m;
+}
--- /dev/null
+/* PASS */
+
+uniform mat2 a;
+uniform mat2 b;
+uniform mat2 c;
+uniform mat2 d;
+uniform mat3 e;
+uniform mat3 f;
+uniform mat3 g;
+uniform mat3 h;
+uniform mat4 i;
+uniform mat4 j;
+uniform mat4 k;
+uniform mat4 l;
+
+void main()
+{
+ mat2 x;
+ mat3 y;
+ mat4 z;
+
+ x = a * b + c / d;
+ y = e * f + g / h;
+ z = i * j + k / l;
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+#version 120
+/* PASS */
+
+uniform mat2x3 a;
+uniform mat3x2 b;
+uniform mat3x3 c;
+uniform mat3x3 d;
+
+void main()
+{
+ mat3x3 x;
+
+ /* Multiplying a 2 column, 3 row matrix with a 3 column, 2 row matrix
+ * results in a 3 column, 3 row matrix.
+ */
+ x = (a * b) + c / d;
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* FAIL - matrix-to-matrix constructors are not available in GLSL 1.10 */
+
+uniform mat3 a;
+
+void main()
+{
+ mat2 m;
+
+ m = mat2(a);
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+#version 120
+/* PASS */
+
+uniform mat3 a;
+
+void main()
+{
+ mat2 m;
+
+ m = mat2(a);
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* FAIL: redefinition of a() */
+
+void a()
+{
+ ;
+}
+
+void a()
+{
+ ;
+}
--- /dev/null
+/* PASS */
+
+void a()
+{
+ ;
+}
+
+void a(float x)
+{
+ ;
+}
--- /dev/null
+/* FAIL - x is redeclared in the function body at the same scope as the
+ * parameter
+ */
+void a(float x, float y)
+{
+ float x;
+
+ x = y;
+}
--- /dev/null
+#version 130
+/* FAIL - inout only allowed in parameter list */
+inout vec4 foo;
--- /dev/null
+/* FAIL - in only allowed in parameter list in GLSL 1.10 */
+in foo;
--- /dev/null
+/* FAIL - out only allowed in parameter list in GLSL 1.10 */
+out vec4 foo;
--- /dev/null
+#version 130
+/* PASS */
+in vec4 foo;
--- /dev/null
+#version 130
+/* PASS */
+out vec4 foo;
--- /dev/null
+/* FAIL - in only allowed in parameter list in GLSL 1.10 */
+void main()
+{
+ in vec4 foo;
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* FAIL - out only allowed in parameter list in GLSL 1.10 */
+void main()
+{
+ out vec4 foo;
+
+ gl_Position = gl_Vertex;
+}
--- /dev/null
+/* PASS */
+#version 120
+
+void main()
+{
+ float a;
+ vec4 b;
+
+ b.x = 6.0;
+ a = b.x;
+}
--- /dev/null
+/* FAIL: assignment of a vec2 to a float */
+#version 120
+
+void main()
+{
+ float a;
+ vec4 b;
+
+ b.x = 6.0;
+ a = b.xy;
+}
--- /dev/null
+/* FAIL - cannot declare a variable as having type `void' */
+void foo;
+++ /dev/null
-/*
- * Copyright © 2008 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 "main/imports.h"
-#include "symbol_table.h"
-#include "hash_table.h"
-
-struct symbol {
- /**
- * Link to the next symbol in the table with the same name
- *
- * The linked list of symbols with the same name is ordered by scope
- * from inner-most to outer-most.
- */
- struct symbol *next_with_same_name;
-
-
- /**
- * Link to the next symbol in the table with the same scope
- *
- * The linked list of symbols with the same scope is unordered. Symbols
- * in this list my have unique names.
- */
- struct symbol *next_with_same_scope;
-
-
- /**
- * Header information for the list of symbols with the same name.
- */
- struct symbol_header *hdr;
-
-
- /**
- * Name space of the symbol
- *
- * Name space are arbitrary user assigned integers. No two symbols can
- * exist in the same name space at the same scope level.
- */
- int name_space;
-
-
- /**
- * Arbitrary user supplied data.
- */
- void *data;
-
- /** Scope depth where this symbol was defined. */
- unsigned depth;
-};
-
-
-/**
- */
-struct symbol_header {
- /** Linkage in list of all headers in a given symbol table. */
- struct symbol_header *next;
-
- /** Symbol name. */
- const char *name;
-
- /** Linked list of symbols with the same name. */
- struct symbol *symbols;
-};
-
-
-/**
- * Element of the scope stack.
- */
-struct scope_level {
- /** Link to next (inner) scope level. */
- struct scope_level *next;
-
- /** Linked list of symbols with the same scope. */
- struct symbol *symbols;
-};
-
-
-/**
- *
- */
-struct _mesa_symbol_table {
- /** Hash table containing all symbols in the symbol table. */
- struct hash_table *ht;
-
- /** Top of scope stack. */
- struct scope_level *current_scope;
-
- /** List of all symbol headers in the table. */
- struct symbol_header *hdr;
-
- /** Current scope depth. */
- unsigned depth;
-};
-
-
-struct _mesa_symbol_table_iterator {
- /**
- * Name space of symbols returned by this iterator.
- */
- int name_space;
-
-
- /**
- * Currently iterated symbol
- *
- * The next call to \c _mesa_symbol_table_iterator_get will return this
- * value. It will also update this value to the value that should be
- * returned by the next call.
- */
- struct symbol *curr;
-};
-
-
-static void
-check_symbol_table(struct _mesa_symbol_table *table)
-{
-#if 1
- struct scope_level *scope;
-
- for (scope = table->current_scope; scope != NULL; scope = scope->next) {
- struct symbol *sym;
-
- for (sym = scope->symbols
- ; sym != NULL
- ; sym = sym->next_with_same_name) {
- const struct symbol_header *const hdr = sym->hdr;
- struct symbol *sym2;
-
- for (sym2 = hdr->symbols
- ; sym2 != NULL
- ; sym2 = sym2->next_with_same_name) {
- assert(sym2->hdr == hdr);
- }
- }
- }
-#endif
-}
-
-void
-_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
-{
- struct scope_level *const scope = table->current_scope;
- struct symbol *sym = scope->symbols;
-
- table->current_scope = scope->next;
- table->depth--;
-
- free(scope);
-
- while (sym != NULL) {
- struct symbol *const next = sym->next_with_same_scope;
- struct symbol_header *const hdr = sym->hdr;
-
- assert(hdr->symbols == sym);
-
- hdr->symbols = sym->next_with_same_name;
-
- free(sym);
-
- sym = next;
- }
-
- check_symbol_table(table);
-}
-
-
-void
-_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
-{
- struct scope_level *const scope = calloc(1, sizeof(*scope));
-
- scope->next = table->current_scope;
- table->current_scope = scope;
- table->depth++;
-}
-
-
-static struct symbol_header *
-find_symbol(struct _mesa_symbol_table *table, const char *name)
-{
- return (struct symbol_header *) hash_table_find(table->ht, name);
-}
-
-
-struct _mesa_symbol_table_iterator *
-_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
- struct symbol_header *const hdr = find_symbol(table, name);
-
- iter->name_space = name_space;
-
- if (hdr != NULL) {
- struct symbol *sym;
-
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- iter->curr = sym;
- break;
- }
- }
- }
-
- return iter;
-}
-
-
-void
-_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
-{
- free(iter);
-}
-
-
-void *
-_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
-{
- return (iter->curr == NULL) ? NULL : iter->curr->data;
-}
-
-
-int
-_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
-{
- struct symbol_header *hdr;
-
- if (iter->curr == NULL) {
- return 0;
- }
-
- hdr = iter->curr->hdr;
- iter->curr = iter->curr->next_with_same_name;
-
- while (iter->curr != NULL) {
- assert(iter->curr->hdr == hdr);
-
- if ((iter->name_space == -1)
- || (iter->curr->name_space == iter->name_space)) {
- return 1;
- }
-
- iter->curr = iter->curr->next_with_same_name;
- }
-
- return 0;
-}
-
-
-/**
- * Determine the scope "distance" of a symbol from the current scope
- *
- * \return
- * A non-negative number for the number of scopes between the current scope
- * and the scope where a symbol was defined. A value of zero means the current
- * scope. A negative number if the symbol does not exist.
- */
-int
-_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct symbol_header *const hdr = find_symbol(table, name);
- struct symbol *sym;
-
- if (hdr != NULL) {
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- assert(sym->depth <= table->depth);
- return sym->depth - table->depth;
- }
- }
- }
-
- return -1;
-}
-
-
-void *
-_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct symbol_header *const hdr = find_symbol(table, name);
-
- if (hdr != NULL) {
- struct symbol *sym;
-
-
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- return sym->data;
- }
- }
- }
-
- return NULL;
-}
-
-
-int
-_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name,
- void *declaration)
-{
- struct symbol_header *hdr;
- struct symbol *sym;
-
- check_symbol_table(table);
-
- hdr = find_symbol(table, name);
-
- check_symbol_table(table);
-
- if (hdr == NULL) {
- hdr = calloc(1, sizeof(*hdr));
- hdr->name = name;
-
- hash_table_insert(table->ht, hdr, name);
- hdr->next = table->hdr;
- table->hdr = hdr;
- }
-
- check_symbol_table(table);
-
- /* If the symbol already exists in this namespace at this scope, it cannot
- * be added to the table.
- */
- for (sym = hdr->symbols
- ; (sym != NULL) && (sym->name_space != name_space)
- ; sym = sym->next_with_same_name) {
- /* empty */
- }
-
- if (sym && (sym->depth == table->depth))
- return -1;
-
- sym = calloc(1, sizeof(*sym));
- sym->next_with_same_name = hdr->symbols;
- sym->next_with_same_scope = table->current_scope->symbols;
- sym->hdr = hdr;
- sym->name_space = name_space;
- sym->data = declaration;
- sym->depth = table->depth;
-
- assert(sym->hdr == hdr);
-
- hdr->symbols = sym;
- table->current_scope->symbols = sym;
-
- check_symbol_table(table);
- return 0;
-}
-
-
-struct _mesa_symbol_table *
-_mesa_symbol_table_ctor(void)
-{
- struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
-
- if (table != NULL) {
- table->ht = hash_table_ctor(32, hash_table_string_hash,
- hash_table_string_compare);
-
- _mesa_symbol_table_push_scope(table);
- }
-
- return table;
-}
-
-
-void
-_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
-{
- struct symbol_header *hdr;
- struct symbol_header *next;
-
- while (table->current_scope != NULL) {
- _mesa_symbol_table_pop_scope(table);
- }
-
- for (hdr = table->hdr; hdr != NULL; hdr = next) {
- next = hdr->next;
- _mesa_free(hdr);
- }
-
- hash_table_dtor(table->ht);
- free(table);
-}
+++ /dev/null
-/*
- * Copyright © 2008 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.
- */
-#ifndef MESA_SYMBOL_TABLE_H
-#define MESA_SYMBOL_TABLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct _mesa_symbol_table;
-struct _mesa_symbol_table_iterator;
-
-extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
-
-extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
-
-extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
- int name_space, const char *name, void *declaration);
-
-extern int _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
- int name_space, const char *name);
-
-extern void *_mesa_symbol_table_find_symbol(
- struct _mesa_symbol_table *symtab, int name_space, const char *name);
-
-extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
-
-extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
-
-extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor(
- struct _mesa_symbol_table *table, int name_space, const char *name);
-
-extern void _mesa_symbol_table_iterator_dtor(
- struct _mesa_symbol_table_iterator *);
-
-extern void *_mesa_symbol_table_iterator_get(
- struct _mesa_symbol_table_iterator *iter);
-
-extern int _mesa_symbol_table_iterator_next(
- struct _mesa_symbol_table_iterator *iter);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* MESA_SYMBOL_TABLE_H */
+++ /dev/null
-#version 120
-/* FAIL - array size type must be int */
-uniform vec4 [3.2] a;
+++ /dev/null
-#version 120
-/* FAIL - array size type must be scalar */
-uniform vec4 [ivec4(3)] a;
+++ /dev/null
-#version 120
-/* PASS */
-uniform vec4 [3] a;
+++ /dev/null
-/* FAIL - array size type must be int */
-uniform vec4 a[3.2];
+++ /dev/null
-/* FAIL - array size type must be scalar */
-uniform vec4 a[ivec4(3)];
+++ /dev/null
-/* PASS */
-uniform vec4 a[3];
+++ /dev/null
-/* FAIL - array size must be > 0 */
-uniform vec4 a[0];
+++ /dev/null
-/* FAIL - array size must be > 0 */
-uniform vec4 a[-1];
+++ /dev/null
-#version 120
-/* PASS */
-
-void main()
-{
- vec4 a[2] = vec4 [2] (vec4(1.0), vec4(2.0));
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* FAIL - array constructors forbidden in GLSL 1.10
- *
- * This can also generate an error because the 'vec4[]' style syntax is
- * illegal in GLSL 1.10.
- */
-void main()
-{
- vec4 a[2] = vec4 [2] (vec4(1.0), vec4(2.0));
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-#version 120
-/* PASS */
-
-void main()
-{
- vec4 a[] = vec4 [] (vec4(1.0), vec4(2.0));
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-#version 120
-/* FAIL - array must have an implicit or explicit size */
-
-void main()
-{
- vec4 a[];
-
- a = vec4 [2] (vec4(1.0), vec4(2.0));
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-#version 120
-/* PASS */
-
-void main()
-{
- vec4 a[2];
-
- a = vec4 [] (vec4(1.0), vec4(2.0));
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* FAIL - attribute cannot have type int */
-attribute int i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have type ivec2 */
-attribute ivec2 i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have type ivec3 */
-attribute ivec3 i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have type ivec4 */
-attribute ivec4 i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have type bool */
-attribute bool i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have type bvec2 */
-attribute bvec2 i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have type bvec3 */
-attribute bvec3 i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have type bvec4 */
-attribute bvec4 i;
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - attribute cannot have array type in GLSL 1.10 */
-attribute vec4 i[10];
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-#version 120
-/* FAIL - attribute cannot have array type in GLSL 1.20 */
-attribute vec4 i[10];
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-#version 130
-/* FAIL - attribute cannot have array type in GLSL 1.30 */
-attribute vec4 i[10];
-
-void main()
-{
- gl_Position = vec4(1.0);
-}
+++ /dev/null
-/* FAIL - :? condition is not bool scalar */
-
-uniform bvec4 a;
-
-void main()
-{
- gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 1.0, 0.0, 1.0);
-}
+++ /dev/null
-/* FAIL - :? condition is not bool scalar */
-
-uniform float a;
-
-void main()
-{
- gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 1.0, 0.0, 1.0);
-}
+++ /dev/null
-/* PASS */
-
-uniform bool a;
-
-void main()
-{
- gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 1.0, 0.0, 1.0);
-}
+++ /dev/null
-/* FAIL - type of second two operands must match */
-
-uniform bool a;
-
-void main()
-{
- gl_Position = (a) ? vec4(1.0, 0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
-}
+++ /dev/null
-#version 120
-/* PASS */
-
-uniform bool a;
-uniform int b;
-
-void main()
-{
- float x;
-
- x = (a) ? 2.0 : b;
- gl_Position = vec4(x);
-}
+++ /dev/null
-/* PASS */
-
-void main()
-{
- gl_Position = vec4(1.0, 1.0, 1.0, 0.0);;
-}
+++ /dev/null
-/* FAIL - cannot construct samplers */
-void main()
-{
- int i;
-
- i = sampler2D(0);
-}
+++ /dev/null
-/* FAIL - cannot construct a matrix from a matrix in GLSL 1.10 */
-
-uniform mat2 a;
-
-void main()
-{
- mat2 b;
-
- b = mat2(a);
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-#version 120
-/* FAIL - matrix must be only parameter to matrix constructor */
-
-uniform mat2 a;
-uniform float x;
-
-void main()
-{
- mat2 b;
-
- b = mat2(a, x);
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* FAIL - too few components supplied to constructor */
-
-uniform vec2 a;
-uniform float x;
-
-void main()
-{
- mat2 b;
-
- b = mat2(a, x);
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-#version 120
-/* PASS */
-
-uniform mat2 a;
-
-void main()
-{
- mat2 b;
-
- b = mat2(a);
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* PASS */
-
-uniform ivec2 a;
-uniform ivec2 b;
-
-void main()
-{
- mat2 c;
-
- c = mat2(a, b);
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* PASS */
-
-uniform float a;
-uniform float b;
-
-void main()
-{
- ivec2 c;
-
- c = ivec2(a, b);
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* PASS */
-
-uniform int a;
-uniform float b;
-uniform bool c;
-
-void main()
-{
- float x;
- int y;
- bool z;
-
- x = float(a);
- x = float(b);
- x = float(c);
-
- y = int(a);
- y = int(b);
- y = int(c);
-
- z = bool(a);
- z = bool(b);
- z = bool(c);
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* FAIL - no function named 'foo' exists */
-
-vec4 bar(float x, float y, float z, float w)
-{
- vec4 v;
- v.x = x;
- v.y = y;
- v.z = z;
- v.w = w;
- return v;
-}
-
-void main()
-{
- gl_Position = foo(1.0, 1.0, 1.0, 0.0);
-}
+++ /dev/null
-/* FAIL - no version of 'foo' matches the call to 'foo' */
-
-vec4 foo(float x, float y, float z, float w)
-{
- vec4 v;
- v.x = x;
- v.y = y;
- v.z = z;
- v.w = w;
- return v;
-}
-
-void main()
-{
- gl_Position = foo(1.0, 1.0, 1.0);
-}
+++ /dev/null
-/* PASS */
-
-vec4 foo(in float x, in float y, float z, float w)
-{
- vec4 v;
- v.x = x;
- v.y = y;
- v.z = z;
- v.w = w;
- return v;
-}
-
-void main()
-{
- gl_Position = foo(1.0, 1.0, 1.0, 0.0);
-}
+++ /dev/null
-/* FAIL - type mismatch in assignment */
-
-vec3 foo(float x, float y, float z)
-{
- vec3 v;
- v.x = x;
- v.y = y;
- v.z = z;
- return v;
-}
-
-void main()
-{
- gl_Position = foo(1.0, 1.0, 1.0);
-}
+++ /dev/null
-/* PASS */
-
-vec4 foo(in float x, in float y, float z, float w)
-{
- vec4 v;
- v.x = x;
- v.y = y;
- v.z = z;
- v.w = w;
- return v;
-}
-
-vec4 foo(in float x)
-{
- vec4 v;
- v.x = x;
- v.y = x;
- v.z = x;
- v.w = x;
-}
-
-void main()
-{
- gl_Position = foo(1.0, 1.0, 1.0, 0.0);
- gl_Position = foo(2.0);
-}
+++ /dev/null
-/* FAIL - if-statement condition is not bool scalar */
-
-uniform bvec4 a;
-
-void main()
-{
- if (a)
- gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
- else
- gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
-}
+++ /dev/null
-/* FAIL - if-statement condition is not bool scalar */
-
-uniform float a;
-
-void main()
-{
- if (a)
- gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
- else
- gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
-}
+++ /dev/null
-/* PASS */
-
-uniform bool a;
-
-void main()
-{
- if (a)
- gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
- else
- gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
-}
+++ /dev/null
-/* PASS */
-
-uniform bvec4 a;
-
-void main()
-{
- if (a.x)
- gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
- else
- gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
-}
+++ /dev/null
-/* FAIL - non-square matrices are not available in GLSL 1.10 */
-
-void main()
-{
- mat2x3 m;
-}
+++ /dev/null
-/* FAIL - non-square matrices are not available in GLSL 1.10 */
-
-void main()
-{
- mat2x4 m;
-}
+++ /dev/null
-/* FAIL - non-square matrices are not available in GLSL 1.10 */
-
-void main()
-{
- mat3x2 m;
-}
+++ /dev/null
-/* FAIL - non-square matrices are not available in GLSL 1.10 */
-
-void main()
-{
- mat3x4 m;
-}
+++ /dev/null
-/* FAIL - non-square matrices are not available in GLSL 1.10 */
-
-void main()
-{
- mat4x2 m;
-}
+++ /dev/null
-/* FAIL - non-square matrices are not available in GLSL 1.10 */
-
-void main()
-{
- mat4x3 m;
-}
+++ /dev/null
-/* PASS */
-
-uniform mat2 a;
-uniform mat2 b;
-uniform mat2 c;
-uniform mat2 d;
-uniform mat3 e;
-uniform mat3 f;
-uniform mat3 g;
-uniform mat3 h;
-uniform mat4 i;
-uniform mat4 j;
-uniform mat4 k;
-uniform mat4 l;
-
-void main()
-{
- mat2 x;
- mat3 y;
- mat4 z;
-
- x = a * b + c / d;
- y = e * f + g / h;
- z = i * j + k / l;
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-#version 120
-/* PASS */
-
-uniform mat2x3 a;
-uniform mat3x2 b;
-uniform mat3x3 c;
-uniform mat3x3 d;
-
-void main()
-{
- mat3x3 x;
-
- /* Multiplying a 2 column, 3 row matrix with a 3 column, 2 row matrix
- * results in a 3 column, 3 row matrix.
- */
- x = (a * b) + c / d;
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* FAIL - matrix-to-matrix constructors are not available in GLSL 1.10 */
-
-uniform mat3 a;
-
-void main()
-{
- mat2 m;
-
- m = mat2(a);
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-#version 120
-/* PASS */
-
-uniform mat3 a;
-
-void main()
-{
- mat2 m;
-
- m = mat2(a);
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* FAIL: redefinition of a() */
-
-void a()
-{
- ;
-}
-
-void a()
-{
- ;
-}
+++ /dev/null
-/* PASS */
-
-void a()
-{
- ;
-}
-
-void a(float x)
-{
- ;
-}
+++ /dev/null
-/* FAIL - x is redeclared in the function body at the same scope as the
- * parameter
- */
-void a(float x, float y)
-{
- float x;
-
- x = y;
-}
+++ /dev/null
-#version 130
-/* FAIL - inout only allowed in parameter list */
-inout vec4 foo;
+++ /dev/null
-/* FAIL - in only allowed in parameter list in GLSL 1.10 */
-in foo;
+++ /dev/null
-/* FAIL - out only allowed in parameter list in GLSL 1.10 */
-out vec4 foo;
+++ /dev/null
-#version 130
-/* PASS */
-in vec4 foo;
+++ /dev/null
-#version 130
-/* PASS */
-out vec4 foo;
+++ /dev/null
-/* FAIL - in only allowed in parameter list in GLSL 1.10 */
-void main()
-{
- in vec4 foo;
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* FAIL - out only allowed in parameter list in GLSL 1.10 */
-void main()
-{
- out vec4 foo;
-
- gl_Position = gl_Vertex;
-}
+++ /dev/null
-/* PASS */
-#version 120
-
-void main()
-{
- float a;
- vec4 b;
-
- b.x = 6.0;
- a = b.x;
-}
+++ /dev/null
-/* FAIL: assignment of a vec2 to a float */
-#version 120
-
-void main()
-{
- float a;
- vec4 b;
-
- b.x = 6.0;
- a = b.xy;
-}
+++ /dev/null
-/* FAIL - cannot declare a variable as having type `void' */
-void foo;